Skip to content
Permalink
Browse files

[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.
  • Loading branch information
nyalldawson committed Jul 27, 2017
1 parent c43a173 commit 98ff7024911ade28c38921c7d7390c26e333e7ab
@@ -195,6 +195,11 @@ class QgsLayoutGuideCollection : QAbstractTableModel
.. seealso:: removeGuide()
%End

void applyGuidesToAllOtherPages( int sourcePage );
%Docstring
Resets all other pages' guides to match the guides from the specified ``sourcePage``.
%End

void update();
%Docstring
Updates the position (and visibility) of all guide line items.
@@ -52,6 +52,7 @@ QgsLayoutGuideWidget::QgsLayoutGuideWidget( QWidget *parent, QgsLayout *layout,
connect( mDeleteVertGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::deleteVerticalGuide );

connect( mClearAllButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::clearAll );
connect( mApplyToAllButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::applyToAll );

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

void QgsLayoutGuideWidget::applyToAll()
{
mLayout->guides().applyGuidesToAllOtherPages( mPage );
}


QgsLayoutGuidePositionDelegate::QgsLayoutGuidePositionDelegate( QgsLayout *layout, QAbstractItemModel *model )
: mLayout( layout )
@@ -44,6 +44,8 @@ class QgsLayoutGuideWidget: public QgsPanelWidget, private Ui::QgsLayoutGuideWid

void clearAll();

void applyToAll();

private:

QgsLayout *mLayout = nullptr;
@@ -355,6 +355,35 @@ void QgsLayoutGuideCollection::clear()
endResetModel();
}

void QgsLayoutGuideCollection::applyGuidesToAllOtherPages( int sourcePage )
{
// remove other page's guides
Q_FOREACH ( QgsLayoutGuide *guide, mGuides )
{
if ( guide->page() != sourcePage )
removeGuide( guide );
}

// remaining guides belong to source page - clone them to other pages
Q_FOREACH ( QgsLayoutGuide *guide, mGuides )
{
for ( int p = 0; p < mLayout->pageCollection()->pageCount(); ++p )
{
if ( p == sourcePage )
continue;

std::unique_ptr< QgsLayoutGuide> newGuide( new QgsLayoutGuide( guide->orientation(), guide->position() ) );
newGuide->setPage( p );
newGuide->setLayout( mLayout );
if ( newGuide->item()->isVisible() )
{
// if invisible, new guide is outside of page bounds
addGuide( newGuide.release() );
}
}
}
}

void QgsLayoutGuideCollection::update()
{
Q_FOREACH ( QgsLayoutGuide *guide, mGuides )
@@ -219,6 +219,11 @@ class CORE_EXPORT QgsLayoutGuideCollection : public QAbstractTableModel
*/
void clear();

/**
* Resets all other pages' guides to match the guides from the specified \a sourcePage.
*/
void applyGuidesToAllOtherPages( int sourcePage );

/**
* Updates the position (and visibility) of all guide line items.
*/
@@ -54,8 +54,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>231</width>
<height>518</height>
<width>217</width>
<height>526</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
@@ -192,8 +192,21 @@
</layout>
</widget>
</item>
<item>
<widget class="QPushButton" name="mApplyToAllButton">
<property name="toolTip">
<string>Resets all other pages' guides to match this page</string>
</property>
<property name="text">
<string>Apply to All Pages</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mClearAllButton">
<property name="toolTip">
<string>Removes all guides from the current page</string>
</property>
<property name="text">
<string>Clear All Guides</string>
</property>
@@ -30,6 +30,8 @@

from qgis.testing import start_app, unittest

import sip

start_app()


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

def testApplyToOtherPages(self):
p = QgsProject()
l = QgsLayout(p)
l.initializeDefaults()
page2 = QgsLayoutItemPage(l)
page2.setPageSize('A6')
l.pageCollection().addPage(page2)
guides = l.guides()

# add some guides
g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5))
guides.addGuide(g1)
g2 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(6))
guides.addGuide(g2)
g3 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(190))
guides.addGuide(g3)
g4 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(1))
g4.setPage(1)
guides.addGuide(g4)

# apply guides from page 0 - should delete g4
guides.applyGuidesToAllOtherPages(0)
self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal, 0), [g1, g3])
self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 0), [g2])
self.assertTrue(sip.isdeleted(g4))

# g3 is outside of page 2 bounds - should not be copied
self.assertEqual(len(guides.guides(QgsLayoutGuide.Horizontal, 1)), 1)
self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal, 1)[0].position().length(), 5)
self.assertEqual(len(guides.guides(QgsLayoutGuide.Vertical, 1)), 1)
self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 1)[0].position().length(), 6)

# apply guides from page 1 to 0
guides.applyGuidesToAllOtherPages(1)
self.assertTrue(sip.isdeleted(g1))
self.assertTrue(sip.isdeleted(g2))
self.assertTrue(sip.isdeleted(g3))
self.assertEqual(len(guides.guides(QgsLayoutGuide.Horizontal, 0)), 1)
self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal, 0)[0].position().length(), 5)
self.assertEqual(len(guides.guides(QgsLayoutGuide.Vertical, 0)), 1)
self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 0)[0].position().length(), 6)


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

0 comments on commit 98ff702

Please sign in to comment.
You can’t perform that action at this time.