QGIS API Documentation  3.21.0-Master (56b4176581)
qgslayoutitemregistry.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutitemregistry.h
3  ------------------------
4  begin : June 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 #ifndef QGSLAYOUTITEMREGISTRY_H
17 #define QGSLAYOUTITEMREGISTRY_H
18 
19 #include "qgis_core.h"
20 #include "qgis_sip.h"
21 #include "qgsapplication.h"
22 #include "qgspathresolver.h"
23 #include <QGraphicsItem> //for QGraphicsItem::UserType
24 #include <QIcon>
25 #include <functional>
26 
27 #include "qgslayoutitem.h" // temporary
28 
29 class QgsLayout;
30 class QgsLayoutView;
31 class QgsLayoutItem;
32 class QgsFillSymbol;
34 
46 {
47  public:
48 
55  QgsLayoutItemAbstractMetadata( int type, const QString &visibleName, const QString &visiblePluralName = QString() )
56  : mType( type )
57  , mVisibleName( visibleName )
58  , mVisibleNamePlural( visiblePluralName.isEmpty() ? visibleName : visiblePluralName )
59  {}
60 
61  virtual ~QgsLayoutItemAbstractMetadata() = default;
62 
66  int type() const { return mType; }
67 
72  QString visibleName() const { return mVisibleName; }
73 
78  QString visiblePluralName() const { return mVisibleNamePlural; }
79 
80  /*
81  * IMPORTANT: While it seems like /Factory/ would be the correct annotations here, that's not
82  * the case.
83  * As per Phil Thomson's advice on https://www.riverbankcomputing.com/pipermail/pyqt/2017-July/039450.html:
84  *
85  * "
86  * /Factory/ is used when the instance returned is guaranteed to be new to Python.
87  * In this case it isn't because it has already been seen when being returned by QgsProcessingAlgorithm::createInstance()
88  * (However for a different sub-class implemented in C++ then it would be the first time it was seen
89  * by Python so the /Factory/ on create() would be correct.)
90  *
91  * You might try using /TransferBack/ on create() instead - that might be the best compromise.
92  * "
93  */
94 
99 
107  virtual void resolvePaths( QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving )
108  {
109  Q_UNUSED( properties )
110  Q_UNUSED( pathResolver )
111  Q_UNUSED( saving )
112  }
113 
114  private:
115 
116  int mType = -1;
117  QString mVisibleName;
118  QString mVisibleNamePlural;
119 };
120 
123 
125 typedef std::function<void( QVariantMap &, const QgsPathResolver &, bool )> QgsLayoutItemPathResolverFunc SIP_SKIP;
126 
127 #ifndef SIP_RUN
128 
136 {
137  public:
138 
145  QgsLayoutItemMetadata( int type, const QString &visibleName, const QString &visiblePluralName,
146  const QgsLayoutItemCreateFunc &pfCreate,
147  const QgsLayoutItemPathResolverFunc &pfPathResolver = nullptr )
148  : QgsLayoutItemAbstractMetadata( type, visibleName, visiblePluralName )
149  , mCreateFunc( pfCreate )
150  , mPathResolverFunc( pfPathResolver )
151  {}
152 
156  QgsLayoutItemCreateFunc createFunction() const { return mCreateFunc; }
157 
161  QgsLayoutItemPathResolverFunc pathResolverFunction() const { return mPathResolverFunc; }
162 
163  QgsLayoutItem *createItem( QgsLayout *layout ) override { return mCreateFunc ? mCreateFunc( layout ) : nullptr; }
164 
165  void resolvePaths( QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving ) override
166  {
167  if ( mPathResolverFunc )
168  mPathResolverFunc( properties, pathResolver, saving );
169  }
170 
171  protected:
172  QgsLayoutItemCreateFunc mCreateFunc = nullptr;
173  QgsLayoutItemPathResolverFunc mPathResolverFunc = nullptr;
174 
175 };
176 
177 #endif
178 
190 {
191  public:
192 
197  QgsLayoutMultiFrameAbstractMetadata( int type, const QString &visibleName )
198  : mType( type )
199  , mVisibleName( visibleName )
200  {}
201 
203 
207  int type() const { return mType; }
208 
212  virtual QIcon icon() const { return QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicRectangle.svg" ) ); }
213 
217  QString visibleName() const { return mVisibleName; }
218 
219  /*
220  * IMPORTANT: While it seems like /Factory/ would be the correct annotations here, that's not
221  * the case.
222  * As per Phil Thomson's advice on https://www.riverbankcomputing.com/pipermail/pyqt/2017-July/039450.html:
223  *
224  * "
225  * /Factory/ is used when the instance returned is guaranteed to be new to Python.
226  * In this case it isn't because it has already been seen when being returned by QgsProcessingAlgorithm::createInstance()
227  * (However for a different sub-class implemented in C++ then it would be the first time it was seen
228  * by Python so the /Factory/ on create() would be correct.)
229  *
230  * You might try using /TransferBack/ on create() instead - that might be the best compromise.
231  * "
232  */
233 
238 
246  virtual void resolvePaths( QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving )
247  {
248  Q_UNUSED( properties )
249  Q_UNUSED( pathResolver )
250  Q_UNUSED( saving )
251  }
252 
253  private:
254 
255  int mType = -1;
256  QString mVisibleName;
257 };
258 
261 
263 typedef std::function<void( QVariantMap &, const QgsPathResolver &, bool )> QgsLayoutMultiFramePathResolverFunc SIP_SKIP;
264 
265 #ifndef SIP_RUN
266 
274 {
275  public:
276 
281  QgsLayoutMultiFrameMetadata( int type, const QString &visibleName,
282  const QgsLayoutMultiFrameCreateFunc &pfCreate,
283  const QgsLayoutMultiFramePathResolverFunc &pfPathResolver = nullptr )
284  : QgsLayoutMultiFrameAbstractMetadata( type, visibleName )
285  , mCreateFunc( pfCreate )
286  , mPathResolverFunc( pfPathResolver )
287  {}
288 
292  QgsLayoutMultiFrameCreateFunc createFunction() const { return mCreateFunc; }
293 
297  QgsLayoutMultiFramePathResolverFunc pathResolverFunction() const { return mPathResolverFunc; }
298 
299  QgsLayoutMultiFrame *createMultiFrame( QgsLayout *layout ) override { return mCreateFunc ? mCreateFunc( layout ) : nullptr; }
300 
301  void resolvePaths( QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving ) override
302  {
303  if ( mPathResolverFunc )
304  mPathResolverFunc( properties, pathResolver, saving );
305  }
306 
307  protected:
308  QgsLayoutMultiFrameCreateFunc mCreateFunc = nullptr;
309  QgsLayoutMultiFramePathResolverFunc mPathResolverFunc = nullptr;
310 
311 };
312 
313 #endif
314 
315 
329 class CORE_EXPORT QgsLayoutItemRegistry : public QObject
330 {
331  Q_OBJECT
332 
333  public:
334 
336  enum ItemType
337  {
338  LayoutItem = QGraphicsItem::UserType + 100,
340 
341  // known item types
342 
343  // WARNING!!!! SIP CASTING OF QgsLayoutItem and QgsLayoutMultiFrame DEPENDS on these
344  // values, and must be updated if any additional types are added
345 
356 
357  // known multi-frame types
358 
359  // WARNING!!!! SIP CASTING OF QgsLayoutItem and QgsLayoutMultiFrame DEPENDS on these
360  // values, and must be updated if any additional types are added
361 
365 
367 
370 
371  // item types provided by plugins
372  PluginItem = LayoutTextTable + 10000,
373  };
374 
383  QgsLayoutItemRegistry( QObject *parent = nullptr );
384 
385  ~QgsLayoutItemRegistry() override;
386 
391  bool populate();
392 
397 
403  QgsLayoutItemAbstractMetadata *itemMetadata( int type ) const;
404 
410  QgsLayoutMultiFrameAbstractMetadata *multiFrameMetadata( int type ) const;
411 
412  /*
413  * IMPORTANT: While it seems like /Factory/ would be the correct annotations here, that's not
414  * the case.
415  * As per Phil Thomson's advice on https://www.riverbankcomputing.com/pipermail/pyqt/2017-July/039450.html:
416  *
417  * "
418  * /Factory/ is used when the instance returned is guaranteed to be new to Python.
419  * In this case it isn't because it has already been seen when being returned by QgsProcessingAlgorithm::createInstance()
420  * (However for a different sub-class implemented in C++ then it would be the first time it was seen
421  * by Python so the /Factory/ on create() would be correct.)
422  *
423  * You might try using /TransferBack/ on create() instead - that might be the best compromise.
424  * "
425  */
426 
431  bool addLayoutItemType( QgsLayoutItemAbstractMetadata *metadata SIP_TRANSFER );
432 
437  bool addLayoutMultiFrameType( QgsLayoutMultiFrameAbstractMetadata *metadata SIP_TRANSFER );
438 
443  QgsLayoutItem *createItem( int type, QgsLayout *layout ) const SIP_TRANSFERBACK;
444 
449  QgsLayoutMultiFrame *createMultiFrame( int type, QgsLayout *layout ) const SIP_TRANSFERBACK;
450 
456  void resolvePaths( int type, QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving ) const;
457 
461  QMap< int, QString> itemTypes() const;
462 
463  signals:
464 
469  void typeAdded( int type, const QString &name );
470 
475  void multiFrameTypeAdded( int type, const QString &name );
476 
477  private:
478 #ifdef SIP_RUN
480 #endif
481 
482  QMap<int, QgsLayoutItemAbstractMetadata *> mMetadata;
483  QMap<int, QgsLayoutMultiFrameAbstractMetadata *> mMultiFrameMetadata;
484 
485 };
486 
487 #if 0
488 #ifndef SIP_RUN
490 //simple item for testing
491 #ifdef ANDROID
492 // For some reason, the Android NDK toolchain requires this to link properly.
493 // Note to self: Please try to remove this again once Qt ships their libs built with gcc-5
494 class CORE_EXPORT TestLayoutItem : public QgsLayoutItem
495 #else
496 class TestLayoutItem : public QgsLayoutItem
497 #endif
498 {
499  Q_OBJECT
500 
501  public:
502 
503  TestLayoutItem( QgsLayout *layout );
504  ~TestLayoutItem() = default;
505 
506  //implement pure virtual methods
507  int type() const override { return QgsLayoutItemRegistry::LayoutItem + 1002; }
508  void draw( QgsRenderContext &context, const QStyleOptionGraphicsItem *itemStyle = nullptr ) override;
509 
510  private:
511  QColor mColor;
512  QgsFillSymbol *mShapeStyleSymbol = nullptr;
513 };
515 #endif
516 #endif
517 
518 #endif //QGSLAYOUTITEMREGISTRY_H
519 
520 
521 
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgsfillsymbol.h:30
Stores metadata about one layout item class.
virtual void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Resolve paths in the item's properties (if there are any paths).
virtual ~QgsLayoutItemAbstractMetadata()=default
QString visibleName() const
Returns a translated, user visible name for the layout item class.
QgsLayoutItemAbstractMetadata(int type, const QString &visibleName, const QString &visiblePluralName=QString())
Constructor for QgsLayoutItemAbstractMetadata with the specified class type and visibleName.
int type() const
Returns the unique item type code for the layout item class.
QString visiblePluralName() const
Returns a translated, user visible name for plurals of the layout item class (e.g.
virtual QgsLayoutItem * createItem(QgsLayout *layout)=0
Creates a layout item of this class for a specified layout.
Convenience metadata class that uses static functions to create layout items and their configuration ...
QgsLayoutItemPathResolverFunc pathResolverFunction() const
Returns the classes' path resolver function.
QgsLayoutItemCreateFunc createFunction() const
Returns the classes' item creation function.
void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving) override
Resolve paths in the item's properties (if there are any paths).
QgsLayoutItemMetadata(int type, const QString &visibleName, const QString &visiblePluralName, const QgsLayoutItemCreateFunc &pfCreate, const QgsLayoutItemPathResolverFunc &pfPathResolver=nullptr)
Constructor for QgsLayoutItemMetadata with the specified class type and visibleName,...
QgsLayoutItem * createItem(QgsLayout *layout) override
Creates a layout item of this class for a specified layout.
Registry of available layout item types.
void typeAdded(int type, const QString &name)
Emitted whenever a new item type is added to the registry, with the specified type and visible name.
@ LayoutManualTable
Manual (fixed) table.
@ LayoutAttributeTable
Attribute table.
@ LayoutPolyline
Polyline shape item.
@ LayoutScaleBar
Scale bar item.
@ LayoutItem
Base class for items.
@ LayoutHtml
Html multiframe item.
@ LayoutTextTable
Preset text table.
@ LayoutFrame
Frame item, part of a QgsLayoutMultiFrame object.
@ LayoutPolygon
Polygon shape item.
QgsLayoutItemRegistry & operator=(const QgsLayoutItemRegistry &rh)=delete
QgsLayoutItemRegistry cannot be copied.
void multiFrameTypeAdded(int type, const QString &name)
Emitted whenever a new multiframe type is added to the registry, with the specified type and visible ...
QgsLayoutItemRegistry(const QgsLayoutItemRegistry &rh)=delete
QgsLayoutItemRegistry cannot be copied.
Base class for graphical items within a QgsLayout.
Stores metadata about one layout multiframe class.
virtual ~QgsLayoutMultiFrameAbstractMetadata()=default
virtual QgsLayoutMultiFrame * createMultiFrame(QgsLayout *layout)=0
Creates a layout multiframe of this class for a specified layout.
virtual QIcon icon() const
Returns an icon representing the layout multiframe type.
int type() const
Returns the unique item type code for the layout multiframe class.
QgsLayoutMultiFrameAbstractMetadata(int type, const QString &visibleName)
Constructor for QgsLayoutMultiFrameAbstractMetadata with the specified class type and visibleName.
virtual void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Resolve paths in the item's properties (if there are any paths).
QString visibleName() const
Returns a translated, user visible name for the layout multiframe class.
Convenience metadata class that uses static functions to create layout multiframes and their configur...
QgsLayoutMultiFramePathResolverFunc pathResolverFunction() const
Returns the classes' path resolver function.
QgsLayoutMultiFrameMetadata(int type, const QString &visibleName, const QgsLayoutMultiFrameCreateFunc &pfCreate, const QgsLayoutMultiFramePathResolverFunc &pfPathResolver=nullptr)
Constructor for QgsLayoutMultiFrameMetadata with the specified class type and visibleName,...
QgsLayoutMultiFrameCreateFunc createFunction() const
Returns the classes' multiframe creation function.
void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving) override
Resolve paths in the item's properties (if there are any paths).
QgsLayoutMultiFrame * createMultiFrame(QgsLayout *layout) override
Creates a layout multiframe of this class for a specified layout.
Abstract base class for layout items with the ability to distribute the content to several frames (Qg...
A graphical widget to display and interact with QgsLayouts.
Definition: qgslayoutview.h:50
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:51
Resolves relative paths into absolute paths and vice versa.
Contains information about the context of a rendering operation.
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_TRANSFER
Definition: qgis_sip.h:36
#define SIP_TRANSFERBACK
Definition: qgis_sip.h:48
std::function< QgsLayoutMultiFrame *(QgsLayout *)> QgsLayoutMultiFrameCreateFunc
Layout multiframe creation function.
std::function< QgsLayoutItem *(QgsLayout *)> QgsLayoutItemCreateFunc
Layout item creation function.
std::function< void(QVariantMap &, const QgsPathResolver &, bool)> QgsLayoutMultiFramePathResolverFunc
Layout multiframe path resolver function.
std::function< void(QVariantMap &, const QgsPathResolver &, bool)> QgsLayoutItemPathResolverFunc
Layout item path resolver function.