Skip to content

Commit 98ff702

Browse files
committedAug 7, 2017
[FEATURE] Add a button in guide manager to apply current page's guides
to all other pages This allows resetting all other pages to use the guide configuration for the current page. Since guides are now single page only (required to handle mixed page size/orientation layouts), this is a shortcut to allow guide configuration to be setup on a single page and then easily transferred to all other pages in the layout.
1 parent c43a173 commit 98ff702

File tree

7 files changed

+106
-2
lines changed

7 files changed

+106
-2
lines changed
 

‎python/core/layout/qgslayoutguidecollection.sip

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,11 @@ class QgsLayoutGuideCollection : QAbstractTableModel
195195
.. seealso:: removeGuide()
196196
%End
197197

198+
void applyGuidesToAllOtherPages( int sourcePage );
199+
%Docstring
200+
Resets all other pages' guides to match the guides from the specified ``sourcePage``.
201+
%End
202+
198203
void update();
199204
%Docstring
200205
Updates the position (and visibility) of all guide line items.

‎src/app/layout/qgslayoutguidewidget.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ QgsLayoutGuideWidget::QgsLayoutGuideWidget( QWidget *parent, QgsLayout *layout,
5252
connect( mDeleteVertGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::deleteVerticalGuide );
5353

5454
connect( mClearAllButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::clearAll );
55+
connect( mApplyToAllButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::applyToAll );
5556

5657
connect( layoutView, &QgsLayoutView::pageChanged, this, &QgsLayoutGuideWidget::pageChanged );
5758
pageChanged( 0 );
@@ -128,6 +129,11 @@ void QgsLayoutGuideWidget::clearAll()
128129
mHozProxyModel->removeRows( 0, mHozProxyModel->rowCount() );
129130
}
130131

132+
void QgsLayoutGuideWidget::applyToAll()
133+
{
134+
mLayout->guides().applyGuidesToAllOtherPages( mPage );
135+
}
136+
131137

132138
QgsLayoutGuidePositionDelegate::QgsLayoutGuidePositionDelegate( QgsLayout *layout, QAbstractItemModel *model )
133139
: mLayout( layout )

‎src/app/layout/qgslayoutguidewidget.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ class QgsLayoutGuideWidget: public QgsPanelWidget, private Ui::QgsLayoutGuideWid
4444

4545
void clearAll();
4646

47+
void applyToAll();
48+
4749
private:
4850

4951
QgsLayout *mLayout = nullptr;

‎src/core/layout/qgslayoutguidecollection.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,35 @@ void QgsLayoutGuideCollection::clear()
355355
endResetModel();
356356
}
357357

358+
void QgsLayoutGuideCollection::applyGuidesToAllOtherPages( int sourcePage )
359+
{
360+
// remove other page's guides
361+
Q_FOREACH ( QgsLayoutGuide *guide, mGuides )
362+
{
363+
if ( guide->page() != sourcePage )
364+
removeGuide( guide );
365+
}
366+
367+
// remaining guides belong to source page - clone them to other pages
368+
Q_FOREACH ( QgsLayoutGuide *guide, mGuides )
369+
{
370+
for ( int p = 0; p < mLayout->pageCollection()->pageCount(); ++p )
371+
{
372+
if ( p == sourcePage )
373+
continue;
374+
375+
std::unique_ptr< QgsLayoutGuide> newGuide( new QgsLayoutGuide( guide->orientation(), guide->position() ) );
376+
newGuide->setPage( p );
377+
newGuide->setLayout( mLayout );
378+
if ( newGuide->item()->isVisible() )
379+
{
380+
// if invisible, new guide is outside of page bounds
381+
addGuide( newGuide.release() );
382+
}
383+
}
384+
}
385+
}
386+
358387
void QgsLayoutGuideCollection::update()
359388
{
360389
Q_FOREACH ( QgsLayoutGuide *guide, mGuides )

‎src/core/layout/qgslayoutguidecollection.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,11 @@ class CORE_EXPORT QgsLayoutGuideCollection : public QAbstractTableModel
219219
*/
220220
void clear();
221221

222+
/**
223+
* Resets all other pages' guides to match the guides from the specified \a sourcePage.
224+
*/
225+
void applyGuidesToAllOtherPages( int sourcePage );
226+
222227
/**
223228
* Updates the position (and visibility) of all guide line items.
224229
*/

‎src/ui/layout/qgslayoutguidewidgetbase.ui

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@
5454
<rect>
5555
<x>0</x>
5656
<y>0</y>
57-
<width>231</width>
58-
<height>518</height>
57+
<width>217</width>
58+
<height>526</height>
5959
</rect>
6060
</property>
6161
<layout class="QVBoxLayout" name="verticalLayout_2">
@@ -192,8 +192,21 @@
192192
</layout>
193193
</widget>
194194
</item>
195+
<item>
196+
<widget class="QPushButton" name="mApplyToAllButton">
197+
<property name="toolTip">
198+
<string>Resets all other pages' guides to match this page</string>
199+
</property>
200+
<property name="text">
201+
<string>Apply to All Pages</string>
202+
</property>
203+
</widget>
204+
</item>
195205
<item>
196206
<widget class="QPushButton" name="mClearAllButton">
207+
<property name="toolTip">
208+
<string>Removes all guides from the current page</string>
209+
</property>
197210
<property name="text">
198211
<string>Clear All Guides</string>
199212
</property>

‎tests/src/python/test_qgslayoutguides.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030

3131
from qgis.testing import start_app, unittest
3232

33+
import sip
34+
3335
start_app()
3436

3537

@@ -249,6 +251,48 @@ def testClear(self):
249251
guides.clear()
250252
self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal), [])
251253

254+
def testApplyToOtherPages(self):
255+
p = QgsProject()
256+
l = QgsLayout(p)
257+
l.initializeDefaults()
258+
page2 = QgsLayoutItemPage(l)
259+
page2.setPageSize('A6')
260+
l.pageCollection().addPage(page2)
261+
guides = l.guides()
262+
263+
# add some guides
264+
g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5))
265+
guides.addGuide(g1)
266+
g2 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(6))
267+
guides.addGuide(g2)
268+
g3 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(190))
269+
guides.addGuide(g3)
270+
g4 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(1))
271+
g4.setPage(1)
272+
guides.addGuide(g4)
273+
274+
# apply guides from page 0 - should delete g4
275+
guides.applyGuidesToAllOtherPages(0)
276+
self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal, 0), [g1, g3])
277+
self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 0), [g2])
278+
self.assertTrue(sip.isdeleted(g4))
279+
280+
# g3 is outside of page 2 bounds - should not be copied
281+
self.assertEqual(len(guides.guides(QgsLayoutGuide.Horizontal, 1)), 1)
282+
self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal, 1)[0].position().length(), 5)
283+
self.assertEqual(len(guides.guides(QgsLayoutGuide.Vertical, 1)), 1)
284+
self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 1)[0].position().length(), 6)
285+
286+
# apply guides from page 1 to 0
287+
guides.applyGuidesToAllOtherPages(1)
288+
self.assertTrue(sip.isdeleted(g1))
289+
self.assertTrue(sip.isdeleted(g2))
290+
self.assertTrue(sip.isdeleted(g3))
291+
self.assertEqual(len(guides.guides(QgsLayoutGuide.Horizontal, 0)), 1)
292+
self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal, 0)[0].position().length(), 5)
293+
self.assertEqual(len(guides.guides(QgsLayoutGuide.Vertical, 0)), 1)
294+
self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 0)[0].position().length(), 6)
295+
252296

253297
if __name__ == '__main__':
254298
unittest.main()

0 commit comments

Comments
 (0)
Please sign in to comment.