Skip to content

Commit a3e2678

Browse files
committedJul 25, 2017
[needs-docs] Start on right click menu for layouts
Currently only contains option for removing the current page and (non-functional) option for setting current page properties
1 parent e885966 commit a3e2678

10 files changed

+172
-1
lines changed
 

‎python/core/layout/qgslayoutpagecollection.sip

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,14 @@ class QgsLayoutPageCollection : QObject
9696
Page numbers in collections begin at 0 - so a ``pageNumber`` of 0 will delete
9797
the first page in the collection.
9898

99+
Calling deletePage() automatically triggers a reflow() of pages.
100+
%End
101+
102+
void deletePage( QgsLayoutItemPage *page );
103+
%Docstring
104+
Deletes a page from the collection. The page will automatically be removed
105+
from the collection's layout().
106+
99107
Calling deletePage() automatically triggers a reflow() of pages.
100108
%End
101109

‎src/app/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ SET(QGIS_APP_SRCS
157157

158158
layout/qgslayoutaddpagesdialog.cpp
159159
layout/qgslayoutdesignerdialog.cpp
160+
layout/qgslayoutappmenuprovider.cpp
160161

161162
locator/qgsinbuiltlocatorfilters.cpp
162163
locator/qgslocatoroptionswidget.cpp
@@ -334,6 +335,7 @@ SET (QGIS_APP_MOC_HDRS
334335
composer/qgsatlascompositionwidget.h
335336

336337
layout/qgslayoutaddpagesdialog.h
338+
layout/qgslayoutappmenuprovider.h
337339
layout/qgslayoutdesignerdialog.h
338340

339341
locator/qgsinbuiltlocatorfilters.h
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/***************************************************************************
2+
qgslayoutappmenuprovider.cpp
3+
---------------------------
4+
Date : July 2017
5+
Copyright : (C) 2017 Nyall Dawson
6+
Email : nyall dot dawson at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgslayoutappmenuprovider.h"
17+
#include "qgslayoutitempage.h"
18+
#include "qgslayout.h"
19+
#include <QMenu>
20+
#include <QMessageBox>
21+
22+
QgsLayoutAppMenuProvider::QgsLayoutAppMenuProvider( QObject *parent )
23+
: QObject( parent )
24+
{
25+
26+
}
27+
28+
QMenu *QgsLayoutAppMenuProvider::createContextMenu( QWidget *parent, QgsLayout *layout, QPointF layoutPoint ) const
29+
{
30+
QMenu *menu = new QMenu( parent );
31+
32+
// is a page under the mouse?
33+
QgsLayoutItemPage *page = layout->pageCollection()->pageAtPoint( layoutPoint );
34+
if ( page )
35+
{
36+
QAction *pagePropertiesAction = new QAction( tr( "Page Properties…" ), menu );
37+
connect( pagePropertiesAction, &QAction::triggered, this, [page]()
38+
{
39+
40+
41+
} );
42+
menu->addAction( pagePropertiesAction );
43+
QAction *removePageAction = new QAction( tr( "Remove Page" ), menu );
44+
connect( removePageAction, &QAction::triggered, this, [layout, page]()
45+
{
46+
if ( QMessageBox::question( nullptr, tr( "Remove Page" ),
47+
tr( "Remove page from layout?" ),
48+
QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes )
49+
{
50+
layout->pageCollection()->deletePage( page );
51+
}
52+
} );
53+
menu->addAction( removePageAction );
54+
}
55+
56+
return menu;
57+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/***************************************************************************
2+
qgslayoutappmenuprovider.h
3+
-------------------------
4+
Date : July 2017
5+
Copyright : (C) 2017 Nyall Dawson
6+
Email : nyall dot dawson at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSLAYOUTAPPMENUPROVIDER_H
17+
#define QGSLAYOUTAPPMENUPROVIDER_H
18+
19+
#include "qgis.h"
20+
#include "qgslayoutview.h"
21+
#include <QObject>
22+
23+
/**
24+
* A menu provider for QgsLayoutView
25+
*/
26+
class QgsLayoutAppMenuProvider : public QObject, public QgsLayoutViewMenuProvider
27+
{
28+
Q_OBJECT
29+
30+
public:
31+
32+
QgsLayoutAppMenuProvider( QObject *parent = nullptr );
33+
34+
QMenu *createContextMenu( QWidget *parent, QgsLayout *layout, QPointF layoutPoint ) const override;
35+
36+
};
37+
38+
#endif // QGSLAYOUTAPPMENUPROVIDER_H

‎src/app/layout/qgslayoutdesignerdialog.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "qgisapp.h"
2222
#include "qgslogger.h"
2323
#include "qgslayout.h"
24+
#include "qgslayoutappmenuprovider.h"
2425
#include "qgslayoutview.h"
2526
#include "qgslayoutviewtooladditem.h"
2627
#include "qgslayoutviewtoolpan.h"
@@ -221,6 +222,9 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
221222

222223
connect( mActionToggleFullScreen, &QAction::toggled, this, &QgsLayoutDesignerDialog::toggleFullScreen );
223224

225+
mMenuProvider = new QgsLayoutAppMenuProvider();
226+
mView->setMenuProvider( mMenuProvider );
227+
224228
restoreWindowState();
225229
}
226230

‎src/app/layout/qgslayoutdesignerdialog.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class QgsLayoutRuler;
3131
class QComboBox;
3232
class QSlider;
3333
class QLabel;
34+
class QgsLayoutAppMenuProvider;
3435

3536
class QgsAppLayoutDesignerInterface : public QgsLayoutDesignerInterface
3637
{
@@ -167,6 +168,8 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
167168
QMap< QString, QToolButton * > mItemGroupToolButtons;
168169
QMap< QString, QMenu * > mItemGroupSubmenus;
169170

171+
QgsLayoutAppMenuProvider *mMenuProvider;
172+
170173
//! Save window state
171174
void saveWindowState();
172175

‎src/core/layout/qgslayoutpagecollection.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,16 @@ void QgsLayoutPageCollection::deletePage( int pageNumber )
190190
reflow();
191191
}
192192

193+
void QgsLayoutPageCollection::deletePage( QgsLayoutItemPage *page )
194+
{
195+
if ( !mPages.contains( page ) )
196+
return;
197+
198+
mPages.removeAll( page );
199+
page->deleteLater();
200+
reflow();
201+
}
202+
193203
void QgsLayoutPageCollection::createDefaultPageStyleSymbol()
194204
{
195205
QgsStringMap properties;

‎src/core/layout/qgslayoutpagecollection.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ class CORE_EXPORT QgsLayoutPageCollection : public QObject
113113
*/
114114
void deletePage( int pageNumber );
115115

116+
/**
117+
* Deletes a page from the collection. The page will automatically be removed
118+
* from the collection's layout().
119+
*
120+
* Calling deletePage() automatically triggers a reflow() of pages.
121+
*/
122+
void deletePage( QgsLayoutItemPage *page );
123+
116124
/**
117125
* Sets the \a symbol to use for drawing pages in the collection.
118126
*

‎src/gui/layout/qgslayoutruler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,8 @@ void QgsLayoutRuler::paintEvent( QPaintEvent *event )
230230
pageCoord += mmDisplay;
231231
totalCoord += mmDisplay;
232232
}
233-
currentPageY += layout->pageCollection()->page( i )->rect().height() + layout->pageCollection()->spaceBetweenPages();
233+
if ( i < endPage )
234+
currentPageY += layout->pageCollection()->page( i )->rect().height() + layout->pageCollection()->spaceBetweenPages();
234235
}
235236
break;
236237
}

‎tests/src/python/test_qgslayoutpagecollection.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,46 @@ def testPages(self):
129129
self.assertTrue(sip.isdeleted(page))
130130
self.assertTrue(sip.isdeleted(page2))
131131

132+
def testDeletePages(self):
133+
"""
134+
Test deleting pages from the collection
135+
"""
136+
p = QgsProject()
137+
l = QgsLayout(p)
138+
collection = l.pageCollection()
139+
140+
# add a page
141+
page = QgsLayoutItemPage(l)
142+
page.setPageSize('A4')
143+
collection.addPage(page)
144+
# add a second page
145+
page2 = QgsLayoutItemPage(l)
146+
page2.setPageSize('A5')
147+
collection.addPage(page2)
148+
149+
# delete page
150+
collection.deletePage(None)
151+
self.assertEqual(collection.pageCount(), 2)
152+
153+
page3 = QgsLayoutItemPage(l)
154+
# try deleting a page not in collection
155+
collection.deletePage(page3)
156+
QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete)
157+
self.assertFalse(sip.isdeleted(page3))
158+
self.assertEqual(collection.pageCount(), 2)
159+
160+
collection.deletePage(page)
161+
self.assertEqual(collection.pageCount(), 1)
162+
self.assertFalse(page in collection.pages())
163+
QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete)
164+
self.assertTrue(sip.isdeleted(page))
165+
166+
collection.deletePage(page2)
167+
self.assertEqual(collection.pageCount(), 0)
168+
self.assertFalse(collection.pages())
169+
QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete)
170+
self.assertTrue(sip.isdeleted(page2))
171+
132172
def testMaxPageWidth(self):
133173
"""
134174
Test calculating maximum page width

0 commit comments

Comments
 (0)
Please sign in to comment.