Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsannotationmanager.cpp 3 : : ------------------------ 4 : : Date : January 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 "qgsannotationmanager.h" 17 : : #include "qgsproject.h" 18 : : #include "qgsannotation.h" 19 : : #include "qgsannotationregistry.h" 20 : : #include "qgsapplication.h" 21 : : #include "qgsstyleentityvisitor.h" 22 : : 23 : 5 : QgsAnnotationManager::QgsAnnotationManager( QgsProject *project ) 24 : 5 : : QObject( project ) 25 : 5 : , mProject( project ) 26 : 10 : { 27 : : 28 : 5 : } 29 : : 30 : 6 : QgsAnnotationManager::~QgsAnnotationManager() 31 : 6 : { 32 : 3 : clear(); 33 : 6 : } 34 : : 35 : 0 : bool QgsAnnotationManager::addAnnotation( QgsAnnotation *annotation ) 36 : : { 37 : 0 : if ( !annotation ) 38 : 0 : return false; 39 : : 40 : 0 : if ( mAnnotations.contains( annotation ) ) 41 : 0 : return true; 42 : : 43 : 0 : mAnnotations << annotation; 44 : 0 : emit annotationAdded( annotation ); 45 : 0 : mProject->setDirty( true ); 46 : 0 : return true; 47 : 0 : } 48 : : 49 : 0 : bool QgsAnnotationManager::removeAnnotation( QgsAnnotation *annotation ) 50 : : { 51 : 0 : if ( !annotation ) 52 : 0 : return false; 53 : : 54 : 0 : if ( !mAnnotations.contains( annotation ) ) 55 : 0 : return false; 56 : : 57 : 0 : emit annotationAboutToBeRemoved( annotation ); 58 : 0 : mAnnotations.removeAll( annotation ); 59 : 0 : delete annotation; 60 : 0 : emit annotationRemoved(); 61 : 0 : mProject->setDirty( true ); 62 : 0 : return true; 63 : 0 : } 64 : : 65 : 11 : void QgsAnnotationManager::clear() 66 : : { 67 : 11 : for ( auto *a : std::as_const( mAnnotations ) ) 68 : : { 69 : 0 : removeAnnotation( a ); 70 : : } 71 : 11 : } 72 : : 73 : 0 : QList<QgsAnnotation *> QgsAnnotationManager::annotations() const 74 : : { 75 : 0 : return mAnnotations; 76 : : } 77 : : 78 : 0 : QList<QgsAnnotation *> QgsAnnotationManager::cloneAnnotations() const 79 : : { 80 : 0 : QList<QgsAnnotation *> results; 81 : 0 : for ( const auto *a : std::as_const( mAnnotations ) ) 82 : : { 83 : 0 : results << a->clone(); 84 : : } 85 : 0 : return results; 86 : 0 : } 87 : : 88 : 0 : bool QgsAnnotationManager::readXml( const QDomElement &element, const QgsReadWriteContext &context ) 89 : : { 90 : 0 : clear(); 91 : : //restore each annotation 92 : 0 : bool result = true; 93 : : 94 : 0 : QDomElement annotationsElem = element.firstChildElement( QStringLiteral( "Annotations" ) ); 95 : : 96 : 0 : QDomElement annotationElement = annotationsElem.firstChildElement( QStringLiteral( "Annotation" ) ); 97 : 0 : while ( ! annotationElement .isNull() ) 98 : : { 99 : 0 : createAnnotationFromXml( annotationElement, context ); 100 : 0 : annotationElement = annotationElement.nextSiblingElement( QStringLiteral( "Annotation" ) ); 101 : : } 102 : : 103 : : // restore old (pre 3.0) project annotations 104 : 0 : if ( annotationElement.isNull() ) 105 : : { 106 : 0 : QDomNodeList oldItemList = element.elementsByTagName( QStringLiteral( "TextAnnotationItem" ) ); 107 : 0 : for ( int i = 0; i < oldItemList.size(); ++i ) 108 : : { 109 : 0 : createAnnotationFromXml( oldItemList.at( i ).toElement(), context ); 110 : 0 : } 111 : 0 : oldItemList = element.elementsByTagName( QStringLiteral( "FormAnnotationItem" ) ); 112 : 0 : for ( int i = 0; i < oldItemList.size(); ++i ) 113 : : { 114 : 0 : createAnnotationFromXml( oldItemList.at( i ).toElement(), context ); 115 : 0 : } 116 : 0 : oldItemList = element.elementsByTagName( QStringLiteral( "HtmlAnnotationItem" ) ); 117 : 0 : for ( int i = 0; i < oldItemList.size(); ++i ) 118 : : { 119 : 0 : createAnnotationFromXml( oldItemList.at( i ).toElement(), context ); 120 : 0 : } 121 : 0 : oldItemList = element.elementsByTagName( QStringLiteral( "SVGAnnotationItem" ) ); 122 : 0 : for ( int i = 0; i < oldItemList.size(); ++i ) 123 : : { 124 : 0 : createAnnotationFromXml( oldItemList.at( i ).toElement(), context ); 125 : 0 : } 126 : 0 : } 127 : : 128 : 0 : return result; 129 : 0 : } 130 : : 131 : 0 : QDomElement QgsAnnotationManager::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const 132 : : { 133 : 0 : QDomElement annotationsElem = doc.createElement( QStringLiteral( "Annotations" ) ); 134 : 0 : QListIterator<QgsAnnotation *> i( mAnnotations ); 135 : : // save lowermost annotation (at end of list) first 136 : 0 : i.toBack(); 137 : 0 : while ( i.hasPrevious() ) 138 : : { 139 : 0 : QgsAnnotation *annotation = i.previous(); 140 : : 141 : 0 : if ( !annotation ) 142 : : { 143 : 0 : continue; 144 : : } 145 : : 146 : 0 : annotation->writeXml( annotationsElem, doc, context ); 147 : : } 148 : 0 : return annotationsElem; 149 : 0 : } 150 : : 151 : 0 : bool QgsAnnotationManager::accept( QgsStyleEntityVisitorInterface *visitor ) const 152 : : { 153 : 0 : if ( mAnnotations.empty() ) 154 : 0 : return true; 155 : : 156 : : // NOTE: if visitEnter returns false it means "don't visit any annotations", not "abort all further visitations" 157 : 0 : if ( !visitor->visitEnter( QgsStyleEntityVisitorInterface::Node( QgsStyleEntityVisitorInterface::NodeType::Annotations, QStringLiteral( "annotations" ), tr( "Annotations" ) ) ) ) 158 : 0 : return true; 159 : : 160 : 0 : for ( QgsAnnotation *a : mAnnotations ) 161 : : { 162 : 0 : if ( !a->accept( visitor ) ) 163 : 0 : return false; 164 : : } 165 : : 166 : 0 : if ( !visitor->visitExit( QgsStyleEntityVisitorInterface::Node( QgsStyleEntityVisitorInterface::NodeType::Annotations, QStringLiteral( "annotations" ), tr( "Annotations" ) ) ) ) 167 : 0 : return false; 168 : : 169 : 0 : return true; 170 : 0 : } 171 : : 172 : 0 : void QgsAnnotationManager::createAnnotationFromXml( const QDomElement &element, const QgsReadWriteContext &context ) 173 : : { 174 : 0 : QString type = element.tagName(); 175 : 0 : QgsAnnotation *annotation = QgsApplication::annotationRegistry()->create( type ); 176 : 0 : if ( !annotation ) 177 : 0 : return; 178 : : 179 : 0 : annotation->readXml( element, context ); 180 : : 181 : 0 : if ( !annotation->mapPositionCrs().isValid() ) 182 : : { 183 : 0 : annotation->setMapPositionCrs( mProject->crs() ); 184 : 0 : } 185 : : 186 : 0 : addAnnotation( annotation ); 187 : 0 : }