mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Annotations are now handled at a project level
This commit implements a new QgsAnnotationManager class, which handles storage, writing and retrieval of annotations. QgsProject has an annotationManager() attached to it. Map canvases sync their visible QgsMapCanvasAnnotationItems to the annotations contained within the project's annotation manager. This moves all management, storage and retrieval of annotations up to core and out of app/canvas.
This commit is contained in:
parent
dd51843e54
commit
4058f4734b
@ -1,8 +1,26 @@
|
||||
%ModuleHeaderCode
|
||||
#include <qgshtmlannotation.h>
|
||||
#include <qgssvgannotation.h>
|
||||
#include <qgstextannotation.h>
|
||||
%End
|
||||
|
||||
class QgsAnnotation : QObject
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsannotation.h>
|
||||
%End
|
||||
|
||||
%ConvertToSubClassCode
|
||||
if ( dynamic_cast< QgsTextAnnotation* > ( sipCpp ) )
|
||||
sipType = sipType_QgsTextAnnotation;
|
||||
else if ( dynamic_cast< QgsSvgAnnotation* > ( sipCpp ) )
|
||||
sipType = sipType_QgsSvgAnnotation;
|
||||
else if ( dynamic_cast< QgsHtmlAnnotation* > ( sipCpp ) )
|
||||
sipType = sipType_QgsHtmlAnnotation;
|
||||
else
|
||||
sipType = NULL;
|
||||
%End
|
||||
|
||||
public:
|
||||
|
||||
QgsAnnotation( QObject* parent /TransferThis/ = nullptr );
|
||||
|
24
python/core/annotations/qgsannotationmanager.sip
Normal file
24
python/core/annotations/qgsannotationmanager.sip
Normal file
@ -0,0 +1,24 @@
|
||||
class QgsAnnotationManager : QObject
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsannotationmanager.h>
|
||||
%End
|
||||
public:
|
||||
|
||||
explicit QgsAnnotationManager( QgsProject* project = nullptr );
|
||||
~QgsAnnotationManager();
|
||||
|
||||
bool addAnnotation( QgsAnnotation* annotation /Transfer/ );
|
||||
bool removeAnnotation( QgsAnnotation* annotation );
|
||||
void clear();
|
||||
QList< QgsAnnotation* > annotations() const;
|
||||
bool readXml( const QDomElement& element, const QDomDocument& doc );
|
||||
QDomElement writeXml( QDomDocument& doc ) const;
|
||||
|
||||
signals:
|
||||
|
||||
void annotationAdded( QgsAnnotation* annotation );
|
||||
void annotationRemoved();
|
||||
void annotationAboutToBeRemoved( QgsAnnotation* annotation );
|
||||
|
||||
};
|
@ -19,6 +19,8 @@ class QgsHtmlAnnotation : QgsAnnotation
|
||||
|
||||
virtual void setAssociatedFeature( const QgsFeature& feature );
|
||||
|
||||
static QgsHtmlAnnotation* create() /Factory/;
|
||||
|
||||
protected:
|
||||
|
||||
void renderAnnotation( QgsRenderContext& context, QSizeF size ) const;
|
||||
|
@ -12,7 +12,9 @@ class QgsSvgAnnotation : QgsAnnotation
|
||||
|
||||
void setFilePath( const QString& file );
|
||||
QString filePath() const;
|
||||
|
||||
|
||||
static QgsSvgAnnotation* create() /Factory/;
|
||||
|
||||
protected:
|
||||
|
||||
void renderAnnotation( QgsRenderContext& context, QSizeF size ) const;
|
||||
|
@ -13,6 +13,8 @@ class QgsTextAnnotation : QgsAnnotation
|
||||
virtual void writeXml( QDomElement& elem, QDomDocument & doc ) const;
|
||||
virtual void readXml( const QDomElement& itemElem, const QDomDocument& doc );
|
||||
|
||||
static QgsTextAnnotation* create() /Factory/;
|
||||
|
||||
protected:
|
||||
|
||||
void renderAnnotation( QgsRenderContext& context, QSizeF size ) const;
|
||||
|
@ -258,8 +258,8 @@ class QgsComposerMap : QgsComposerItem
|
||||
/** Sets canvas pointer (necessary to query and draw map canvas items)*/
|
||||
void setMapCanvas( QGraphicsView* canvas /Transfer/ );
|
||||
|
||||
void setDrawCanvasItems( bool b );
|
||||
bool drawCanvasItems() const;
|
||||
void setDrawAnnotations( bool draw );
|
||||
bool drawAnnotations() const;
|
||||
|
||||
/** Returns the conversion factor map units -> mm*/
|
||||
double mapUnitsToMM() const;
|
||||
|
@ -175,6 +175,7 @@
|
||||
%Include qgsxmlutils.sip
|
||||
|
||||
%Include annotations/qgsannotation.sip
|
||||
%Include annotations/qgsannotationmanager.sip
|
||||
%Include annotations/qgshtmlannotation.sip
|
||||
%Include annotations/qgssvgannotation.sip
|
||||
%Include annotations/qgstextannotation.sip
|
||||
|
@ -325,6 +325,8 @@ class QgsProject : QObject, QgsExpressionContextGenerator
|
||||
*/
|
||||
QgsMapThemeCollection* mapThemeCollection();
|
||||
|
||||
QgsAnnotationManager* annotationManager();
|
||||
|
||||
/**
|
||||
* Set a list of layers which should not be taken into account on map identification
|
||||
*/
|
||||
|
@ -683,7 +683,7 @@ void QgsComposerMapWidget::updateGuiElements()
|
||||
mKeepLayerStylesCheckBox->setCheckState( mComposerMap->keepLayerStyles() ? Qt::Checked : Qt::Unchecked );
|
||||
|
||||
//draw canvas items
|
||||
if ( mComposerMap->drawCanvasItems() )
|
||||
if ( mComposerMap->drawAnnotations() )
|
||||
{
|
||||
mDrawCanvasItemsCheckBox->setCheckState( Qt::Checked );
|
||||
}
|
||||
@ -951,7 +951,7 @@ void QgsComposerMapWidget::on_mDrawCanvasItemsCheckBox_stateChanged( int state )
|
||||
}
|
||||
|
||||
mComposerMap->beginCommand( tr( "Canvas items toggled" ) );
|
||||
mComposerMap->setDrawCanvasItems( state == Qt::Checked );
|
||||
mComposerMap->setDrawAnnotations( state == Qt::Checked );
|
||||
mUpdatePreviewButton->setEnabled( false ); //prevent crashes because of many button clicks
|
||||
mComposerMap->setCacheUpdated( false );
|
||||
mComposerMap->cache();
|
||||
|
@ -106,6 +106,8 @@
|
||||
#include "qgsapplayertreeviewmenuprovider.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsactionmanager.h"
|
||||
#include "qgsannotationmanager.h"
|
||||
#include "qgsannotationregistry.h"
|
||||
#include "qgsattributetabledialog.h"
|
||||
#include "qgsattributedialog.h"
|
||||
#include "qgsauthmanager.h"
|
||||
@ -777,6 +779,10 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
|
||||
functionProfile( &QgisApp::updateRecentProjectPaths, this, QStringLiteral( "Update recent project paths" ) );
|
||||
functionProfile( &QgisApp::updateProjectFromTemplates, this, QStringLiteral( "Update project from templates" ) );
|
||||
functionProfile( &QgisApp::legendLayerSelectionChanged, this, QStringLiteral( "Legend layer selection changed" ) );
|
||||
|
||||
QgsApplication::annotationRegistry()->addAnnotationType( QgsAnnotationMetadata( QStringLiteral( "FormAnnotationItem" ), &QgsFormAnnotation::create ) );
|
||||
connect( QgsProject::instance()->annotationManager(), &QgsAnnotationManager::annotationAdded, this, &QgisApp::annotationCreated );
|
||||
|
||||
mSaveRollbackInProgress = false;
|
||||
|
||||
QFileSystemWatcher* projectsTemplateWatcher = new QFileSystemWatcher( this );
|
||||
@ -1416,6 +1422,12 @@ void QgisApp::dropEventTimeout()
|
||||
mMapCanvas->refresh();
|
||||
}
|
||||
|
||||
void QgisApp::annotationCreated( QgsAnnotation* annotation )
|
||||
{
|
||||
// create canvas annotation item for annotation
|
||||
QgsMapCanvasAnnotationItem* canvasItem = new QgsMapCanvasAnnotationItem( annotation, mMapCanvas );
|
||||
Q_UNUSED( canvasItem ); //item is already added automatically to canvas scene
|
||||
}
|
||||
|
||||
void QgisApp::registerCustomDropHandler( QgsCustomDropHandler* handler )
|
||||
{
|
||||
@ -1817,31 +1829,6 @@ void QgisApp::showStyleManager()
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void QgisApp::writeAnnotationItemsToProject( QDomDocument& doc )
|
||||
{
|
||||
QDomElement documentElem = doc.documentElement();
|
||||
if ( documentElem.isNull() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QgsMapCanvasAnnotationItem*> items = annotationItems();
|
||||
QgsMapCanvasAnnotationItem* item = nullptr;
|
||||
QListIterator<QgsMapCanvasAnnotationItem*> i( items );
|
||||
// save lowermost annotation (at end of list) first
|
||||
i.toBack();
|
||||
while ( i.hasPrevious() )
|
||||
{
|
||||
item = i.previous();
|
||||
|
||||
if ( !item || !item->annotation() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
item->annotation()->writeXml( documentElem, doc );
|
||||
}
|
||||
}
|
||||
|
||||
void QgisApp::showPythonDialog()
|
||||
{
|
||||
if ( !mPythonUtils || !mPythonUtils->isEnabled() )
|
||||
@ -2831,11 +2818,8 @@ void QgisApp::setupConnections()
|
||||
this, SLOT( readProject( const QDomDocument & ) ) );
|
||||
connect( QgsProject::instance(), SIGNAL( writeProject( QDomDocument & ) ),
|
||||
this, SLOT( writeProject( QDomDocument & ) ) );
|
||||
connect( QgsProject::instance(), SIGNAL( writeProject( QDomDocument& ) ),
|
||||
this, SLOT( writeAnnotationItemsToProject( QDomDocument& ) ) );
|
||||
|
||||
connect( QgsProject::instance(), SIGNAL( readProject( const QDomDocument & ) ), this, SLOT( loadComposersFromProject( const QDomDocument& ) ) );
|
||||
connect( QgsProject::instance(), SIGNAL( readProject( const QDomDocument & ) ), this, SLOT( loadAnnotationItemsFromProject( const QDomDocument& ) ) );
|
||||
|
||||
connect( this, SIGNAL( projectRead() ),
|
||||
this, SLOT( fileOpenedOKAfterLaunch() ) );
|
||||
@ -6936,70 +6920,6 @@ void QgisApp::on_mPrintComposersMenu_aboutToShow()
|
||||
mPrintComposersMenu->addActions( acts );
|
||||
}
|
||||
|
||||
bool QgisApp::loadAnnotationItemsFromProject( const QDomDocument& doc )
|
||||
{
|
||||
if ( !mMapCanvas )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
removeAnnotationItems();
|
||||
|
||||
if ( doc.isNull() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QList< QgsAnnotation* > annotations;
|
||||
|
||||
QDomNodeList textItemList = doc.elementsByTagName( QStringLiteral( "TextAnnotationItem" ) );
|
||||
for ( int i = 0; i < textItemList.size(); ++i )
|
||||
{
|
||||
QgsTextAnnotation* newTextItem = new QgsTextAnnotation();
|
||||
newTextItem->readXml( textItemList.at( i ).toElement(), doc );
|
||||
annotations << newTextItem;
|
||||
}
|
||||
|
||||
QDomNodeList formItemList = doc.elementsByTagName( QStringLiteral( "FormAnnotationItem" ) );
|
||||
for ( int i = 0; i < formItemList.size(); ++i )
|
||||
{
|
||||
QgsFormAnnotation* newFormItem = new QgsFormAnnotation();
|
||||
newFormItem->readXml( formItemList.at( i ).toElement(), doc );
|
||||
annotations << newFormItem;
|
||||
}
|
||||
|
||||
#ifdef WITH_QTWEBKIT
|
||||
QDomNodeList htmlItemList = doc.elementsByTagName( QStringLiteral( "HtmlAnnotationItem" ) );
|
||||
for ( int i = 0; i < htmlItemList.size(); ++i )
|
||||
{
|
||||
QgsHtmlAnnotation* newHtmlItem = new QgsHtmlAnnotation();
|
||||
newHtmlItem->readXml( htmlItemList.at( i ).toElement(), doc );
|
||||
annotations << newHtmlItem;
|
||||
}
|
||||
#endif
|
||||
|
||||
QDomNodeList svgItemList = doc.elementsByTagName( QStringLiteral( "SVGAnnotationItem" ) );
|
||||
for ( int i = 0; i < svgItemList.size(); ++i )
|
||||
{
|
||||
QgsSvgAnnotation* newSvgItem = new QgsSvgAnnotation();
|
||||
newSvgItem->readXml( svgItemList.at( i ).toElement(), doc );
|
||||
annotations << newSvgItem;
|
||||
}
|
||||
|
||||
Q_FOREACH ( QgsAnnotation* annotation, annotations )
|
||||
{
|
||||
if ( !annotation->mapPositionCrs().isValid() )
|
||||
{
|
||||
annotation->setMapPositionCrs( mMapCanvas->mapSettings().destinationCrs() );
|
||||
}
|
||||
|
||||
// create canvas annotation items
|
||||
QgsMapCanvasAnnotationItem* canvasItem = new QgsMapCanvasAnnotationItem( annotation, mMapCanvas );
|
||||
Q_UNUSED( canvasItem ); //item is already added automatically to canvas scene
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void QgisApp::showPinnedLabels( bool show )
|
||||
{
|
||||
qobject_cast<QgsMapToolPinLabels*>( mMapTools.mPinLabels )->showPinnedLabels( show );
|
||||
|
@ -39,6 +39,7 @@ class QValidator;
|
||||
|
||||
class QgisAppInterface;
|
||||
class QgisAppStyleSheet;
|
||||
class QgsAnnotation;
|
||||
class QgsMapCanvasAnnotationItem;
|
||||
class QgsAuthManager;
|
||||
class QgsBookmarks;
|
||||
@ -1308,16 +1309,12 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
||||
|
||||
void showStyleManager();
|
||||
|
||||
void writeAnnotationItemsToProject( QDomDocument& doc );
|
||||
|
||||
//! Creates the composer instances in a project file and adds them to the menu
|
||||
bool loadComposersFromProject( const QDomDocument& doc );
|
||||
|
||||
//! Slot to handle display of composers menu, e.g. sorting
|
||||
void on_mPrintComposersMenu_aboutToShow();
|
||||
|
||||
bool loadAnnotationItemsFromProject( const QDomDocument& doc );
|
||||
|
||||
//! Toggles whether to show pinned labels
|
||||
void showPinnedLabels( bool show );
|
||||
//! Activates pin labels tool
|
||||
@ -1390,6 +1387,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
||||
//! Handles processing of dropped mimedata
|
||||
void dropEventTimeout();
|
||||
|
||||
void annotationCreated( QgsAnnotation* annotation );
|
||||
|
||||
signals:
|
||||
|
||||
/** Emitted when a key is pressed and we want non widget sublasses to be able
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "qgsformannotation.h"
|
||||
#include "qgsmapcanvasannotationitem.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsannotationmanager.h"
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QGraphicsScene>
|
||||
@ -84,12 +86,8 @@ void QgsFormAnnotationDialog::on_mBrowseToolButton_clicked()
|
||||
|
||||
void QgsFormAnnotationDialog::deleteItem()
|
||||
{
|
||||
QGraphicsScene* scene = mItem->scene();
|
||||
if ( scene )
|
||||
{
|
||||
scene->removeItem( mItem );
|
||||
}
|
||||
delete mItem;
|
||||
if ( mItem && mItem->annotation() )
|
||||
QgsProject::instance()->annotationManager()->removeAnnotation( mItem->annotation() );
|
||||
mItem = nullptr;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "qgsannotationwidget.h"
|
||||
#include "qgsmapcanvasannotationitem.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsannotationmanager.h"
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QGraphicsScene>
|
||||
@ -83,12 +85,8 @@ void QgsHtmlAnnotationDialog::on_mBrowseToolButton_clicked()
|
||||
|
||||
void QgsHtmlAnnotationDialog::deleteItem()
|
||||
{
|
||||
QGraphicsScene* scene = mItem->scene();
|
||||
if ( scene )
|
||||
{
|
||||
scene->removeItem( mItem );
|
||||
}
|
||||
delete mItem;
|
||||
if ( mItem && mItem->annotation() )
|
||||
QgsProject::instance()->annotationManager()->removeAnnotation( mItem->annotation() );
|
||||
mItem = nullptr;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "qgssvgannotation.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgscsexception.h"
|
||||
#include "qgsannotationmanager.h"
|
||||
#include <QDialog>
|
||||
#include <QMouseEvent>
|
||||
|
||||
@ -146,15 +147,11 @@ void QgsMapToolAnnotation::keyPressEvent( QKeyEvent* e )
|
||||
{
|
||||
if ( e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete )
|
||||
{
|
||||
if ( mCanvas && mCanvas->scene() )
|
||||
QCursor neutralCursor( item->cursorShapeForAction( QgsMapCanvasAnnotationItem::NoAction ) );
|
||||
QgsProject::instance()->annotationManager()->removeAnnotation( item->annotation() );
|
||||
if ( mCanvas )
|
||||
{
|
||||
QCursor neutralCursor( item->cursorShapeForAction( QgsMapCanvasAnnotationItem::NoAction ) );
|
||||
mCanvas->scene()->removeItem( item );
|
||||
delete item;
|
||||
mCanvas->setCursor( neutralCursor );
|
||||
QgsProject::instance()->setDirty( true ); // TODO QGIS3: Rework the whole annotation code to be MVC compliant, see PR #2506
|
||||
|
||||
// Override default shortcut management in MapCanvas
|
||||
e->ignore();
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "qgsannotationwidget.h"
|
||||
#include "qgssvgannotation.h"
|
||||
#include "qgsmapcanvasannotationitem.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsannotationmanager.h"
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QGraphicsScene>
|
||||
@ -89,12 +91,8 @@ void QgsSvgAnnotationDialog::applySettingsToItem()
|
||||
|
||||
void QgsSvgAnnotationDialog::deleteItem()
|
||||
{
|
||||
QGraphicsScene* scene = mItem->scene();
|
||||
if ( scene )
|
||||
{
|
||||
scene->removeItem( mItem );
|
||||
}
|
||||
delete mItem;
|
||||
if ( mItem && mItem->annotation() )
|
||||
QgsProject::instance()->annotationManager()->removeAnnotation( mItem->annotation() );
|
||||
mItem = nullptr;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "qgsannotationwidget.h"
|
||||
#include "qgstextannotation.h"
|
||||
#include "qgsmapcanvasannotationitem.h"
|
||||
#include "qgsannotationmanager.h"
|
||||
#include "qgsproject.h"
|
||||
#include <QColorDialog>
|
||||
#include <QGraphicsScene>
|
||||
|
||||
@ -156,12 +158,8 @@ void QgsTextAnnotationDialog::blockAllSignals( bool block )
|
||||
|
||||
void QgsTextAnnotationDialog::deleteItem()
|
||||
{
|
||||
QGraphicsScene* scene = mItem->scene();
|
||||
if ( scene )
|
||||
{
|
||||
scene->removeItem( mItem );
|
||||
}
|
||||
delete mItem;
|
||||
if ( mItem && mItem->annotation() )
|
||||
QgsProject::instance()->annotationManager()->removeAnnotation( mItem->annotation() );
|
||||
mItem = nullptr;
|
||||
}
|
||||
|
||||
|
@ -780,6 +780,8 @@ SET(QGIS_CORE_HDRS
|
||||
qgswebview.h
|
||||
qgslocalec.h
|
||||
|
||||
annotations/qgsannotationregistry.h
|
||||
|
||||
auth/qgsauthcertutils.h
|
||||
auth/qgsauthconfig.h
|
||||
auth/qgsauthcrypto.h
|
||||
|
@ -353,7 +353,10 @@ void QgsAnnotation::_readXml( const QDomElement& annotationElem, const QDomDocum
|
||||
QPointF pos;
|
||||
pos.setX( annotationElem.attribute( QStringLiteral( "canvasPosX" ), QStringLiteral( "0" ) ).toDouble() );
|
||||
pos.setY( annotationElem.attribute( QStringLiteral( "canvasPosY" ), QStringLiteral( "0" ) ).toDouble() );
|
||||
mRelativePosition = pos;
|
||||
if ( pos.x() >= 1 || pos.x() < 0 || pos.y() < 0 || pos.y() >= 1 )
|
||||
mRelativePosition = QPointF();
|
||||
else
|
||||
mRelativePosition = pos;
|
||||
QgsPoint mapPos;
|
||||
mapPos.setX( annotationElem.attribute( QStringLiteral( "mapPosX" ), QStringLiteral( "0" ) ).toDouble() );
|
||||
mapPos.setY( annotationElem.attribute( QStringLiteral( "mapPosY" ), QStringLiteral( "0" ) ).toDouble() );
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "qgsannotationmanager.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsannotation.h"
|
||||
#include "qgsannotationregistry.h"
|
||||
|
||||
QgsAnnotationManager::QgsAnnotationManager( QgsProject* project )
|
||||
: QObject( project )
|
||||
@ -39,6 +40,7 @@ bool QgsAnnotationManager::addAnnotation( QgsAnnotation* annotation )
|
||||
|
||||
mAnnotations << annotation;
|
||||
emit annotationAdded( annotation );
|
||||
mProject->setDirty( true );
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -54,6 +56,7 @@ bool QgsAnnotationManager::removeAnnotation( QgsAnnotation* annotation )
|
||||
mAnnotations.removeAll( annotation );
|
||||
delete annotation;
|
||||
emit annotationRemoved();
|
||||
mProject->setDirty( true );
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -75,30 +78,73 @@ bool QgsAnnotationManager::readXml( const QDomElement& element, const QDomDocume
|
||||
clear();
|
||||
//restore each annotation
|
||||
bool result = true;
|
||||
QDomNodeList annotationNodes = element.elementsByTagName( QStringLiteral( "Annotations" ) );
|
||||
|
||||
QDomElement annotationsElem = element.firstChildElement( QStringLiteral( "Annotations" ) );
|
||||
|
||||
QDomNodeList annotationNodes = annotationsElem.elementsByTagName( QStringLiteral( "Annotation" ) );
|
||||
for ( int i = 0; i < annotationNodes.size(); ++i )
|
||||
{
|
||||
QgsAnnotation* a = createAnnotationFromXml( annotationNodes.at( i ).toElement(), doc );
|
||||
if ( !a )
|
||||
{
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
addAnnotation( a );
|
||||
createAnnotationFromXml( annotationNodes.at( i ).toElement(), doc );
|
||||
}
|
||||
|
||||
// restore old (pre 3.0) project annotations
|
||||
QDomNodeList oldItemList = element.elementsByTagName( QStringLiteral( "TextAnnotationItem" ) );
|
||||
for ( int i = 0; i < oldItemList.size(); ++i )
|
||||
{
|
||||
createAnnotationFromXml( oldItemList.at( i ).toElement(), doc );
|
||||
}
|
||||
oldItemList = element.elementsByTagName( QStringLiteral( "FormAnnotationItem" ) );
|
||||
for ( int i = 0; i < oldItemList.size(); ++i )
|
||||
{
|
||||
createAnnotationFromXml( oldItemList.at( i ).toElement(), doc );
|
||||
}
|
||||
oldItemList = element.elementsByTagName( QStringLiteral( "HtmlAnnotationItem" ) );
|
||||
for ( int i = 0; i < oldItemList.size(); ++i )
|
||||
{
|
||||
createAnnotationFromXml( oldItemList.at( i ).toElement(), doc );
|
||||
}
|
||||
oldItemList = element.elementsByTagName( QStringLiteral( "SVGAnnotationItem" ) );
|
||||
for ( int i = 0; i < oldItemList.size(); ++i )
|
||||
{
|
||||
createAnnotationFromXml( oldItemList.at( i ).toElement(), doc );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QgsAnnotation* QgsAnnotationManager::createAnnotationFromXml( const QDomElement& element, const QDomDocument& ) const
|
||||
QDomElement QgsAnnotationManager::writeXml( QDomDocument& doc ) const
|
||||
{
|
||||
QDomNodeList annotationNodeList = element.elementsByTagName( QStringLiteral( "Annotation" ) );
|
||||
QDomElement annotationsElem = doc.createElement( QStringLiteral( "Annotations" ) );
|
||||
QListIterator<QgsAnnotation*> i( mAnnotations );
|
||||
// save lowermost annotation (at end of list) first
|
||||
i.toBack();
|
||||
while ( i.hasPrevious() )
|
||||
{
|
||||
QgsAnnotation* annotation = i.previous();
|
||||
|
||||
if ( annotationNodeList.size() > 0 )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
if ( !annotation )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
annotation->writeXml( annotationsElem, doc );
|
||||
}
|
||||
return annotationsElem;
|
||||
}
|
||||
|
||||
void QgsAnnotationManager::createAnnotationFromXml( const QDomElement& element, const QDomDocument& doc )
|
||||
{
|
||||
QString type = element.tagName();
|
||||
QgsAnnotation* annotation = QgsApplication::annotationRegistry()->create( type );
|
||||
if ( !annotation )
|
||||
return;
|
||||
|
||||
annotation->readXml( element, doc );
|
||||
|
||||
if ( !annotation->mapPositionCrs().isValid() )
|
||||
{
|
||||
annotation->setMapPositionCrs( mProject->crs() );
|
||||
}
|
||||
|
||||
addAnnotation( annotation );
|
||||
}
|
||||
|
@ -67,8 +67,19 @@ class CORE_EXPORT QgsAnnotationManager : public QObject
|
||||
*/
|
||||
QList< QgsAnnotation* > annotations() const;
|
||||
|
||||
/**
|
||||
* Reads the manager's state from a DOM element, restoring all annotations
|
||||
* present in the XML document.
|
||||
* @see writeXml()
|
||||
*/
|
||||
bool readXml( const QDomElement& element, const QDomDocument& doc );
|
||||
|
||||
/**
|
||||
* Returns a DOM element representing the state of the manager.
|
||||
* @see readXml()
|
||||
*/
|
||||
QDomElement writeXml( QDomDocument& doc ) const;
|
||||
|
||||
signals:
|
||||
|
||||
//! Emitted when a annotation has been added to the manager
|
||||
@ -86,7 +97,7 @@ class CORE_EXPORT QgsAnnotationManager : public QObject
|
||||
|
||||
QList< QgsAnnotation* > mAnnotations;
|
||||
|
||||
QgsAnnotation* createAnnotationFromXml( const QDomElement& element, const QDomDocument& doc ) const;
|
||||
void createAnnotationFromXml( const QDomElement& element, const QDomDocument& doc );
|
||||
|
||||
};
|
||||
|
||||
|
131
src/core/annotations/qgsannotationregistry.h
Normal file
131
src/core/annotations/qgsannotationregistry.h
Normal file
@ -0,0 +1,131 @@
|
||||
/***************************************************************************
|
||||
qgsannotationregistry.h
|
||||
-----------------------
|
||||
Date : January 2017
|
||||
Copyright : (C) 2017 Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSANNOTATIONREGISTRY_H
|
||||
#define QGSANNOTATIONREGISTRY_H
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgsannotation.h"
|
||||
#include "qgstextannotation.h"
|
||||
#include "qgssvgannotation.h"
|
||||
#include "qgshtmlannotation.h"
|
||||
#include <QString>
|
||||
#include <functional>
|
||||
|
||||
///@cond PRIVATE
|
||||
|
||||
// None of this is stable API!
|
||||
|
||||
//! Creates a new annotation object
|
||||
typedef std::function < QgsAnnotation*() > QgsCreateAnnotationFunc;
|
||||
|
||||
/**
|
||||
* \class QgsAnnotationMetadata
|
||||
* \ingroup core
|
||||
* Metadata item for an annotation type within a QgsAnnotationRegistry.
|
||||
* \note Added in QGIS 3.0
|
||||
*/
|
||||
class CORE_EXPORT QgsAnnotationMetadata
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsAnnotationMetadata. \a typeName should be a unique string
|
||||
* identifying the annotation type.
|
||||
*/
|
||||
QgsAnnotationMetadata( const QString& typeName, QgsCreateAnnotationFunc createFunc )
|
||||
: mTypeName( typeName )
|
||||
, mCreateFunc( createFunc )
|
||||
{}
|
||||
|
||||
/**
|
||||
* Returns the annotation type.
|
||||
*/
|
||||
QString type() const { return mTypeName; }
|
||||
|
||||
/**
|
||||
* Creates a new annotation of the associated type.
|
||||
*/
|
||||
QgsAnnotation* createAnnotation() const { return mCreateFunc ? mCreateFunc() : nullptr ; }
|
||||
|
||||
private:
|
||||
|
||||
QString mTypeName;
|
||||
QgsCreateAnnotationFunc mCreateFunc = nullptr;
|
||||
|
||||
QgsAnnotationMetadata() = default;
|
||||
friend class QMap< QString, QgsAnnotationMetadata >;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* \class QgsAnnotationRegistry
|
||||
* \ingroup core
|
||||
* Handles registration and creation of annotation item types.
|
||||
* \note Added in QGIS 3.0
|
||||
*/
|
||||
class CORE_EXPORT QgsAnnotationRegistry
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsAnnotationRegistry. The registry is automatically populated
|
||||
* with several standard annotation types.
|
||||
*/
|
||||
QgsAnnotationRegistry()
|
||||
{
|
||||
addAnnotationType( QgsAnnotationMetadata( QStringLiteral( "TextAnnotationItem" ), QgsTextAnnotation::create ) );
|
||||
#ifdef WITH_QTWEBKIT
|
||||
addAnnotationType( QgsAnnotationMetadata( QStringLiteral( "HtmlAnnotationItem" ), QgsHtmlAnnotation::create ) );
|
||||
#endif
|
||||
addAnnotationType( QgsAnnotationMetadata( QStringLiteral( "SVGAnnotationItem" ), QgsSvgAnnotation::create ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new annotation type to the registry. Returns true if adding the type
|
||||
* was successful, or false if an annotation with duplicate type already exists
|
||||
* in the registry.
|
||||
*/
|
||||
bool addAnnotationType( const QgsAnnotationMetadata& metadata )
|
||||
{
|
||||
if ( mMetadata.contains( metadata.type() ) )
|
||||
return false;
|
||||
|
||||
mMetadata.insert( metadata.type(), metadata );
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new annotation of the specified type. Returns nullptr if no
|
||||
* matching annotations types were found.
|
||||
*/
|
||||
QgsAnnotation* create( const QString& typeName ) const
|
||||
{
|
||||
if ( !mMetadata.contains( typeName ) )
|
||||
return nullptr;
|
||||
|
||||
return mMetadata.value( typeName ).createAnnotation();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
QMap< QString, QgsAnnotationMetadata > mMetadata;
|
||||
|
||||
};
|
||||
|
||||
///@endcond
|
||||
|
||||
#endif // QGSANNOTATIONREGISTRY_H
|
@ -63,6 +63,11 @@ class CORE_EXPORT QgsHtmlAnnotation: public QgsAnnotation
|
||||
|
||||
void setAssociatedFeature( const QgsFeature& feature ) override;
|
||||
|
||||
/**
|
||||
* Returns a new QgsHtmlAnnotation object.
|
||||
*/
|
||||
static QgsHtmlAnnotation* create() { return new QgsHtmlAnnotation(); }
|
||||
|
||||
protected:
|
||||
|
||||
void renderAnnotation( QgsRenderContext& context, QSizeF size ) const override;
|
||||
|
@ -54,6 +54,11 @@ class CORE_EXPORT QgsSvgAnnotation: public QgsAnnotation
|
||||
*/
|
||||
QString filePath() const { return mFilePath; }
|
||||
|
||||
/**
|
||||
* Returns a new QgsSvgAnnotation object.
|
||||
*/
|
||||
static QgsSvgAnnotation* create() { return new QgsSvgAnnotation(); }
|
||||
|
||||
protected:
|
||||
|
||||
void renderAnnotation( QgsRenderContext& context, QSizeF size ) const override;
|
||||
|
@ -56,6 +56,11 @@ class CORE_EXPORT QgsTextAnnotation: public QgsAnnotation
|
||||
virtual void writeXml( QDomElement& elem, QDomDocument & doc ) const override;
|
||||
virtual void readXml( const QDomElement& itemElem, const QDomDocument& doc ) override;
|
||||
|
||||
/**
|
||||
* Returns a new QgsTextAnnotation object.
|
||||
*/
|
||||
static QgsTextAnnotation* create() { return new QgsTextAnnotation(); }
|
||||
|
||||
protected:
|
||||
|
||||
void renderAnnotation( QgsRenderContext& context, QSizeF size ) const override;
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "qgsexpression.h"
|
||||
#include "qgsmapthemecollection.h"
|
||||
#include "qgsannotation.h"
|
||||
#include "qgsannotationmanager.h"
|
||||
|
||||
#include "qgssymbollayerutils.h" //for pointOnLineWithDistance
|
||||
|
||||
@ -56,7 +57,7 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition, int x, int y, int w
|
||||
, mFollowVisibilityPreset( false )
|
||||
, mUpdatesEnabled( true )
|
||||
, mMapCanvas( nullptr )
|
||||
, mDrawCanvasItems( true )
|
||||
, mDrawAnnotations( true )
|
||||
, mAtlasDriven( false )
|
||||
, mAtlasScalingMode( Auto )
|
||||
, mAtlasMargin( 0.10 )
|
||||
@ -101,7 +102,7 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition )
|
||||
, mFollowVisibilityPreset( false )
|
||||
, mUpdatesEnabled( true )
|
||||
, mMapCanvas( nullptr )
|
||||
, mDrawCanvasItems( true )
|
||||
, mDrawAnnotations( true )
|
||||
, mAtlasDriven( false )
|
||||
, mAtlasScalingMode( Auto )
|
||||
, mAtlasMargin( 0.10 )
|
||||
@ -360,7 +361,7 @@ void QgsComposerMap::paint( QPainter* painter, const QStyleOptionGraphicsItem*,
|
||||
painter->restore();
|
||||
|
||||
//draw canvas items
|
||||
drawCanvasItems( painter );
|
||||
drawAnnotations( painter );
|
||||
}
|
||||
else if ( mComposition->plotStyle() == QgsComposition::Print ||
|
||||
mComposition->plotStyle() == QgsComposition::Postscript )
|
||||
@ -399,7 +400,7 @@ void QgsComposerMap::paint( QPainter* painter, const QStyleOptionGraphicsItem*,
|
||||
painter->restore();
|
||||
|
||||
//draw canvas items
|
||||
drawCanvasItems( painter );
|
||||
drawAnnotations( painter );
|
||||
|
||||
mDrawing = false;
|
||||
}
|
||||
@ -1202,7 +1203,7 @@ bool QgsComposerMap::writeXml( QDomElement& elem, QDomDocument & doc ) const
|
||||
composerMapElem.setAttribute( QStringLiteral( "keepLayerSet" ), QStringLiteral( "false" ) );
|
||||
}
|
||||
|
||||
if ( mDrawCanvasItems )
|
||||
if ( mDrawAnnotations )
|
||||
{
|
||||
composerMapElem.setAttribute( QStringLiteral( "drawCanvasItems" ), QStringLiteral( "true" ) );
|
||||
}
|
||||
@ -1362,11 +1363,11 @@ bool QgsComposerMap::readXml( const QDomElement& itemElem, const QDomDocument& d
|
||||
QString drawCanvasItemsFlag = itemElem.attribute( QStringLiteral( "drawCanvasItems" ), QStringLiteral( "true" ) );
|
||||
if ( drawCanvasItemsFlag.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
mDrawCanvasItems = true;
|
||||
mDrawAnnotations = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDrawCanvasItems = false;
|
||||
mDrawAnnotations = false;
|
||||
}
|
||||
|
||||
mLayerStyleOverrides.clear();
|
||||
@ -1864,37 +1865,31 @@ QPointF QgsComposerMap::mapToItemCoords( QPointF mapCoords ) const
|
||||
return QPointF( xItem, yItem );
|
||||
}
|
||||
|
||||
void QgsComposerMap::drawCanvasItems( QPainter* painter )
|
||||
void QgsComposerMap::drawAnnotations( QPainter* painter )
|
||||
{
|
||||
if ( !mMapCanvas || !mDrawCanvasItems )
|
||||
if ( !mComposition || !mComposition->project() || !mDrawAnnotations )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QGraphicsItem*> itemList = mMapCanvas->items();
|
||||
if ( itemList.size() < 1 )
|
||||
{
|
||||
QList< QgsAnnotation* > annotations = mComposition->project()->annotationManager()->annotations();
|
||||
if ( annotations.isEmpty() )
|
||||
return;
|
||||
}
|
||||
QGraphicsItem* currentItem = nullptr;
|
||||
|
||||
QgsRenderContext rc = QgsComposerUtils::createRenderContextForMap( this, painter );
|
||||
rc.setForceVectorOutput( true );
|
||||
rc.setExpressionContext( createExpressionContext() );
|
||||
for ( int i = itemList.size() - 1; i >= 0; --i )
|
||||
Q_FOREACH ( QgsAnnotation* annotation, annotations )
|
||||
{
|
||||
currentItem = itemList.at( i );
|
||||
|
||||
const QgsAnnotation* annotation = dynamic_cast< const QgsAnnotation* >( currentItem );
|
||||
if ( !annotation )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
drawCanvasItem( annotation, rc );
|
||||
drawAnnotation( annotation, rc );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerMap::drawCanvasItem( const QgsAnnotation* annotation, QgsRenderContext& context )
|
||||
void QgsComposerMap::drawAnnotation( const QgsAnnotation* annotation, QgsRenderContext& context )
|
||||
{
|
||||
if ( !annotation || !annotation->isVisible() || !context.painter() || !context.painter()->device() )
|
||||
{
|
||||
|
@ -352,8 +352,17 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
|
||||
//! Sets canvas pointer (necessary to query and draw map canvas items)
|
||||
void setMapCanvas( QGraphicsView* canvas ) { mMapCanvas = canvas; }
|
||||
|
||||
void setDrawCanvasItems( bool b ) { mDrawCanvasItems = b; }
|
||||
bool drawCanvasItems() const { return mDrawCanvasItems; }
|
||||
/**
|
||||
* Sets whether annotations are drawn within the composer map.
|
||||
* @see drawAnnotations()
|
||||
*/
|
||||
void setDrawAnnotations( bool draw ) { mDrawAnnotations = draw; }
|
||||
|
||||
/**
|
||||
* Returns whether annotations are drawn within the composer map.
|
||||
* @see setDrawAnnotations()
|
||||
*/
|
||||
bool drawAnnotations() const { return mDrawAnnotations; }
|
||||
|
||||
//! Returns the conversion factor map units -> mm
|
||||
double mapUnitsToMM() const;
|
||||
@ -571,7 +580,7 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
|
||||
QRectF mCurrentRectangle;
|
||||
QGraphicsView* mMapCanvas;
|
||||
//! True if annotation items, rubber band, etc. from the main canvas should be displayed
|
||||
bool mDrawCanvasItems;
|
||||
bool mDrawAnnotations;
|
||||
|
||||
/** Adjusts an extent rectangle to match the provided item width and height, so that extent
|
||||
* center of extent remains the same */
|
||||
@ -606,8 +615,8 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
|
||||
@param yShift in: shift in y direction (in item units), out: yShift in map units*/
|
||||
void transformShift( double& xShift, double& yShift ) const;
|
||||
|
||||
void drawCanvasItems( QPainter* painter );
|
||||
void drawCanvasItem( const QgsAnnotation* item, QgsRenderContext& context );
|
||||
void drawAnnotations( QPainter* painter );
|
||||
void drawAnnotation( const QgsAnnotation* item, QgsRenderContext& context );
|
||||
QPointF composerMapPosForItem( const QgsAnnotation* item ) const;
|
||||
|
||||
enum PartType
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "qgspluginlayerregistry.h"
|
||||
#include "qgsmessagelog.h"
|
||||
#include "processing/qgsprocessingregistry.h"
|
||||
#include "qgsannotationregistry.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
@ -135,6 +136,7 @@ QgsApplication::QgsApplication( int & argc, char ** argv, bool GUIenabled, const
|
||||
mGpsConnectionRegistry = new QgsGPSConnectionRegistry();
|
||||
mPluginLayerRegistry = new QgsPluginLayerRegistry();
|
||||
mProcessingRegistry = new QgsProcessingRegistry();
|
||||
mAnnotationRegistry = new QgsAnnotationRegistry();
|
||||
|
||||
init( customConfigPath ); // init can also be called directly by e.g. unit tests that don't inherit QApplication.
|
||||
}
|
||||
@ -266,6 +268,7 @@ void QgsApplication::init( QString customConfigPath )
|
||||
|
||||
QgsApplication::~QgsApplication()
|
||||
{
|
||||
delete mAnnotationRegistry;
|
||||
delete mProcessingRegistry;
|
||||
delete mActionScopeRegistry;
|
||||
delete mTaskManager;
|
||||
@ -1604,6 +1607,11 @@ QgsProcessingRegistry*QgsApplication::processingRegistry()
|
||||
return instance()->mProcessingRegistry;
|
||||
}
|
||||
|
||||
QgsAnnotationRegistry*QgsApplication::annotationRegistry()
|
||||
{
|
||||
return instance()->mAnnotationRegistry;
|
||||
}
|
||||
|
||||
QgsFieldFormatterRegistry* QgsApplication::fieldFormatterRegistry()
|
||||
{
|
||||
return instance()->mFieldFormatterRegistry;
|
||||
|
@ -38,6 +38,7 @@ class QgsDataItemProviderRegistry;
|
||||
class QgsPluginLayerRegistry;
|
||||
class QgsMessageLog;
|
||||
class QgsProcessingRegistry;
|
||||
class QgsAnnotationRegistry;
|
||||
|
||||
/** \ingroup core
|
||||
* Extends QApplication to provide access to QGIS specific resources such
|
||||
@ -462,6 +463,13 @@ class CORE_EXPORT QgsApplication : public QApplication
|
||||
*/
|
||||
static QgsProcessingRegistry* processingRegistry();
|
||||
|
||||
/**
|
||||
* Returns the application's annotation registry, used for managing annotation types.
|
||||
* @note added in QGIS 3.0
|
||||
* @note not available in Python bindings
|
||||
*/
|
||||
static QgsAnnotationRegistry* annotationRegistry();
|
||||
|
||||
#ifdef ANDROID
|
||||
//dummy method to workaround sip generation issue issue
|
||||
bool x11EventFilter( XEvent * event )
|
||||
@ -607,6 +615,7 @@ class CORE_EXPORT QgsApplication : public QApplication
|
||||
QgsPluginLayerRegistry* mPluginLayerRegistry = nullptr;
|
||||
QgsMessageLog* mMessageLog = nullptr;
|
||||
QgsProcessingRegistry* mProcessingRegistry = nullptr;
|
||||
QgsAnnotationRegistry* mAnnotationRegistry = nullptr;
|
||||
QString mNullRepresentation;
|
||||
};
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "qgsrasterlayer.h"
|
||||
#include "qgsrectangle.h"
|
||||
#include "qgsrelationmanager.h"
|
||||
#include "qgsannotationmanager.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsmapthemecollection.h"
|
||||
#include "qgslayerdefinition.h"
|
||||
@ -319,6 +320,7 @@ QgsProject::QgsProject( QObject* parent )
|
||||
, mBadLayerHandler( new QgsProjectBadLayerHandler() )
|
||||
, mSnappingConfig( this )
|
||||
, mRelationManager( new QgsRelationManager( this ) )
|
||||
, mAnnotationManager( new QgsAnnotationManager( this ) )
|
||||
, mRootGroup( new QgsLayerTreeGroup )
|
||||
, mAutoTransaction( false )
|
||||
, mEvaluateDefaultValues( false )
|
||||
@ -453,6 +455,7 @@ void QgsProject::clear()
|
||||
|
||||
mEmbeddedLayers.clear();
|
||||
mRelationManager->clear();
|
||||
mAnnotationManager->clear();
|
||||
mSnappingConfig.reset();
|
||||
emit snappingConfigChanged();
|
||||
|
||||
@ -916,6 +919,8 @@ bool QgsProject::read()
|
||||
emit mapThemeCollectionChanged();
|
||||
mMapThemeCollection->readXml( *doc );
|
||||
|
||||
mAnnotationManager->readXml( doc->documentElement(), *doc );
|
||||
|
||||
// reassign change dependencies now that all layers are loaded
|
||||
QMap<QString, QgsMapLayer*> existingMaps = mapLayers();
|
||||
for ( QMap<QString, QgsMapLayer*>::iterator it = existingMaps.begin(); it != existingMaps.end(); it++ )
|
||||
@ -1284,6 +1289,9 @@ bool QgsProject::write()
|
||||
|
||||
mMapThemeCollection->writeXml( *doc );
|
||||
|
||||
QDomElement annotationsElem = mAnnotationManager->writeXml( *doc );
|
||||
qgisNode.appendChild( annotationsElem );
|
||||
|
||||
// now wrap it up and ship it to the project file
|
||||
doc->normalize(); // XXX I'm not entirely sure what this does
|
||||
|
||||
@ -2144,6 +2152,11 @@ QgsMapThemeCollection* QgsProject::mapThemeCollection()
|
||||
return mMapThemeCollection.data();
|
||||
}
|
||||
|
||||
QgsAnnotationManager* QgsProject::annotationManager()
|
||||
{
|
||||
return mAnnotationManager.data();
|
||||
}
|
||||
|
||||
void QgsProject::setNonIdentifiableLayers( const QList<QgsMapLayer*>& layers )
|
||||
{
|
||||
QStringList currentLayers = nonIdentifiableLayers();
|
||||
|
@ -53,6 +53,7 @@ class QgsRelationManager;
|
||||
class QgsTolerance;
|
||||
class QgsTransactionGroup;
|
||||
class QgsVectorLayer;
|
||||
class QgsAnnotationManager;
|
||||
|
||||
|
||||
/** \ingroup core
|
||||
@ -384,6 +385,12 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
|
||||
*/
|
||||
QgsMapThemeCollection* mapThemeCollection();
|
||||
|
||||
/**
|
||||
* Returns pointer to the project's annotation manager.
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
QgsAnnotationManager* annotationManager();
|
||||
|
||||
/**
|
||||
* Set a list of layers which should not be taken into account on map identification
|
||||
*/
|
||||
@ -960,6 +967,8 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
|
||||
|
||||
QgsRelationManager* mRelationManager;
|
||||
|
||||
QScopedPointer<QgsAnnotationManager> mAnnotationManager;
|
||||
|
||||
QgsLayerTreeGroup* mRootGroup;
|
||||
|
||||
QgsLayerTreeRegistryBridge* mLayerTreeRegistryBridge;
|
||||
|
@ -43,6 +43,11 @@ class GUI_EXPORT QgsFormAnnotation: public QgsAnnotation
|
||||
|
||||
void setAssociatedFeature( const QgsFeature& feature ) override;
|
||||
|
||||
/**
|
||||
* Returns a new QgsFormAnnotation object.
|
||||
*/
|
||||
static QgsFormAnnotation* create() { return new QgsFormAnnotation(); }
|
||||
|
||||
protected:
|
||||
|
||||
void renderAnnotation( QgsRenderContext& context, QSizeF size ) const override;
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "qgsfeatureiterator.h"
|
||||
#include "qgscsexception.h"
|
||||
#include "qgssymbollayerutils.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsannotationmanager.h"
|
||||
#include <QPainter>
|
||||
|
||||
|
||||
@ -39,15 +41,14 @@ QgsMapCanvasAnnotationItem::QgsMapCanvasAnnotationItem( QgsAnnotation* annotatio
|
||||
|
||||
connect( mMapCanvas, &QgsMapCanvas::layersChanged, this, &QgsMapCanvasAnnotationItem::onCanvasLayersChanged );
|
||||
connect( mAnnotation, &QgsAnnotation::mapLayerChanged, this, &QgsMapCanvasAnnotationItem::onCanvasLayersChanged );
|
||||
|
||||
//lifetime is tied to annotation!
|
||||
connect( mAnnotation, &QgsAnnotation::destroyed, this, &QgsMapCanvasAnnotationItem::deleteLater );
|
||||
|
||||
updatePosition();
|
||||
setFeatureForMapPosition();
|
||||
}
|
||||
|
||||
QgsMapCanvasAnnotationItem::~QgsMapCanvasAnnotationItem()
|
||||
{
|
||||
delete mAnnotation;
|
||||
}
|
||||
|
||||
void QgsMapCanvasAnnotationItem::updatePosition()
|
||||
{
|
||||
if ( !mAnnotation )
|
||||
|
@ -52,11 +52,9 @@ class GUI_EXPORT QgsMapCanvasAnnotationItem: public QObject, public QgsMapCanvas
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor for QgsMapCanvasAnnotationItem. This item takes ownership
|
||||
* of the annotation.
|
||||
* Constructor for QgsMapCanvasAnnotationItem.
|
||||
*/
|
||||
QgsMapCanvasAnnotationItem( QgsAnnotation* annotation, QgsMapCanvas* mapCanvas );
|
||||
~QgsMapCanvasAnnotationItem();
|
||||
|
||||
/**
|
||||
* Returns the item's annotation.
|
||||
|
Loading…
x
Reference in New Issue
Block a user