QGIS API Documentation 3.36.0-Maidenhead (09951dc0acf)
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 "qgslayout.h"
19#include "qgslayoutview.h"
20#include "qgsdoublespinbox.h"
23#include "qgslayoutundostack.h"
24
26 : QgsPanelWidget( parent )
27 , mLayout( layout )
28{
29 setupUi( this );
30 setPanelTitle( tr( "Guides" ) );
31
32 mHozProxyModel = new QgsLayoutGuideProxyModel( mHozGuidesTableView, Qt::Horizontal, 0 );
33 mHozProxyModel->setSourceModel( &mLayout->guides() );
34 mVertProxyModel = new QgsLayoutGuideProxyModel( mVertGuidesTableView, Qt::Vertical, 0 );
35 mVertProxyModel->setSourceModel( &mLayout->guides() );
36
37 mHozGuidesTableView->setModel( mHozProxyModel );
38 mVertGuidesTableView->setModel( mVertProxyModel );
39
40 mHozGuidesTableView->setEditTriggers( QAbstractItemView::AllEditTriggers );
41 mVertGuidesTableView->setEditTriggers( QAbstractItemView::AllEditTriggers );
42
43 mHozGuidesTableView->setItemDelegateForColumn( 0, new QgsLayoutGuidePositionDelegate( mHozGuidesTableView ) );
44 mHozGuidesTableView->setItemDelegateForColumn( 1, new QgsLayoutGuideUnitDelegate( mHozGuidesTableView ) );
45
46 mVertGuidesTableView->setItemDelegateForColumn( 0, new QgsLayoutGuidePositionDelegate( mVertGuidesTableView ) );
47 mVertGuidesTableView->setItemDelegateForColumn( 1, new QgsLayoutGuideUnitDelegate( mVertGuidesTableView ) );
48
49 connect( mAddHozGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::addHorizontalGuide );
50 connect( mAddVertGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::addVerticalGuide );
51
52 connect( mDeleteHozGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::deleteHorizontalGuide );
53 connect( mDeleteVertGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::deleteVerticalGuide );
54
55 connect( mClearAllButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::clearAll );
56 connect( mApplyToAllButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::applyToAll );
57
58 connect( mLayout->pageCollection(), &QgsLayoutPageCollection::changed, this, &QgsLayoutGuideWidget::updatePageCount );
59 updatePageCount();
60 connect( mPageNumberComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int )
61 {
62 setCurrentPage( mPageNumberComboBox->currentData().toInt() );
63 } );
64
66 setCurrentPage( 0 );
67}
68
69void QgsLayoutGuideWidget::addHorizontalGuide()
70{
71 std::unique_ptr< QgsLayoutGuide > newGuide( new QgsLayoutGuide( Qt::Horizontal, QgsLayoutMeasurement( 0 ), mLayout->pageCollection()->page( mPage ) ) );
72 mLayout->guides().addGuide( newGuide.release() );
73}
74
75void QgsLayoutGuideWidget::addVerticalGuide()
76{
77 std::unique_ptr< QgsLayoutGuide > newGuide( new QgsLayoutGuide( Qt::Vertical, QgsLayoutMeasurement( 0 ), mLayout->pageCollection()->page( mPage ) ) );
78 mLayout->guides().addGuide( newGuide.release() );
79}
80
81void QgsLayoutGuideWidget::deleteHorizontalGuide()
82{
83 mLayout->undoStack()->beginMacro( tr( "Remove Horizontal Guides" ) );
84 const auto constSelectedIndexes = mHozGuidesTableView->selectionModel()->selectedIndexes();
85 for ( const QModelIndex &index : constSelectedIndexes )
86 {
87 mHozGuidesTableView->closePersistentEditor( index );
88 if ( index.column() == 0 )
89 mHozProxyModel->removeRow( index.row() );
90 }
91 mLayout->undoStack()->endMacro();
92}
93
94void QgsLayoutGuideWidget::deleteVerticalGuide()
95{
96 mLayout->undoStack()->beginMacro( tr( "Remove Vertical Guides" ) );
97 const auto constSelectedIndexes = mVertGuidesTableView->selectionModel()->selectedIndexes();
98 for ( const QModelIndex &index : constSelectedIndexes )
99 {
100 mVertGuidesTableView->closePersistentEditor( index );
101 if ( index.column() == 0 )
102 mVertProxyModel->removeRow( index.row() );
103 }
104 mLayout->undoStack()->endMacro();
105}
106
108{
109 mPage = page;
110
111 // have to close any open editors - or we'll get a crash
112
113 // qt - y u no do this for me?
114 const auto horizontalSelectedIndexes = mHozGuidesTableView->selectionModel()->selectedIndexes();
115 for ( const QModelIndex &index : horizontalSelectedIndexes )
116 {
117 mHozGuidesTableView->closePersistentEditor( index );
118 }
119 const auto verticalSelectedIndexes = mVertGuidesTableView->selectionModel()->selectedIndexes();
120 for ( const QModelIndex &index : verticalSelectedIndexes )
121 {
122 mVertGuidesTableView->closePersistentEditor( index );
123 }
124
125 mHozProxyModel->setPage( page );
126 mVertProxyModel->setPage( page );
127
128 whileBlocking( mPageNumberComboBox )->setCurrentIndex( page );
129}
130
131void QgsLayoutGuideWidget::clearAll()
132{
133 // qt - y u no do this for me?
134 const auto horizontalSelectedIndexes = mHozGuidesTableView->selectionModel()->selectedIndexes();
135 for ( const QModelIndex &index : horizontalSelectedIndexes )
136 {
137 mHozGuidesTableView->closePersistentEditor( index );
138 }
139 const auto verticalSelectedIndexes = mVertGuidesTableView->selectionModel()->selectedIndexes();
140 for ( const QModelIndex &index : verticalSelectedIndexes )
141 {
142 mVertGuidesTableView->closePersistentEditor( index );
143 }
144
145 mLayout->undoStack()->beginMacro( tr( "Remove All Guides" ) );
146 mVertProxyModel->removeRows( 0, mVertProxyModel->rowCount() );
147 mHozProxyModel->removeRows( 0, mHozProxyModel->rowCount() );
148 mLayout->undoStack()->endMacro();
149}
150
151void QgsLayoutGuideWidget::applyToAll()
152{
153 mLayout->guides().applyGuidesToAllOtherPages( mPage );
154}
155
156void QgsLayoutGuideWidget::updatePageCount()
157{
158 const int prevPage = mPageNumberComboBox->currentIndex();
159 mPageNumberComboBox->clear();
160 for ( int i = 0; i < mLayout->pageCollection()->pageCount(); ++ i )
161 mPageNumberComboBox->addItem( QString::number( i + 1 ), i );
162
163 if ( mPageNumberComboBox->count() > prevPage )
164 mPageNumberComboBox->setCurrentIndex( prevPage );
165}
166
167
169 : QStyledItemDelegate( parent )
170{
171
172}
173
174QWidget *QgsLayoutGuidePositionDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &, const QModelIndex & ) const
175{
176 QgsDoubleSpinBox *spin = new QgsDoubleSpinBox( parent );
177 spin->setMinimum( 0 );
178 spin->setMaximum( 1000000 );
179 spin->setDecimals( 2 );
180 spin->setShowClearButton( false );
181 connect( spin, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( double )
182 {
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, [ = ]( Qgis::LayoutUnit )
204 {
205 // we want to update on every unit change, not just the final
206 const_cast< QgsLayoutGuideUnitDelegate * >( this )->emit commitData( unitsCb );
207 } );
208 return unitsCb;
209}
210
211void QgsLayoutGuideUnitDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
212{
213 QgsLayoutUnitsComboBox *cb = qobject_cast< QgsLayoutUnitsComboBox *>( editor );
214 model->setData( index, static_cast< int >( cb->unit() ), static_cast< int >( QgsLayoutGuideCollection::CustomRole::Units ) );
215}
216
LayoutUnit
Layout measurement units.
Definition qgis.h:4213
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:5048