QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
qgsauxiliarystorage.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsauxiliarystorage.cpp - description
3  -------------------
4  begin : Aug 28, 2017
5  copyright : (C) 2017 by Paul Blottiere
6  email : paul.blottiere@oslandia.com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgsauxiliarystorage.h"
19 #include "qgslogger.h"
20 #include "qgsspatialiteutils.h"
21 #include "qgsproject.h"
22 #include "qgsvectorlayerlabeling.h"
23 #include "qgsdiagramrenderer.h"
24 #include "qgsmemoryproviderutils.h"
25 #include "qgssymbollayer.h"
26 
27 #include <sqlite3.h>
28 #include <QFile>
29 
30 #define AS_JOINFIELD QStringLiteral( "ASPK" )
31 #define AS_EXTENSION QStringLiteral( "qgd" )
32 #define AS_JOINPREFIX QStringLiteral( "auxiliary_storage_" )
33 typedef QVector<QgsPalLayerSettings::Property> PalPropertyList;
35 {
61 } ) )
62 
63 //
64 // QgsAuxiliaryLayer
65 //
66 
67 QgsAuxiliaryLayer::QgsAuxiliaryLayer( const QString &pkField, const QString &filename, const QString &table, QgsVectorLayer *vlayer )
68  : QgsVectorLayer( QStringLiteral( "%1|layername=%2" ).arg( filename, table ),
69  QStringLiteral( "%1_auxiliarystorage" ).arg( table ), QStringLiteral( "ogr" ) )
70  , mFileName( filename )
71  , mTable( table )
72  , mLayer( vlayer )
73 {
74  // init join info
75  mJoinInfo.setPrefix( AS_JOINPREFIX );
76  mJoinInfo.setJoinLayer( this );
77  mJoinInfo.setJoinFieldName( AS_JOINFIELD );
78  mJoinInfo.setTargetFieldName( pkField );
79  mJoinInfo.setEditable( true );
80  mJoinInfo.setUpsertOnEdit( true );
81  mJoinInfo.setCascadedDelete( true );
82  mJoinInfo.setJoinFieldNamesBlockList( QStringList() << QStringLiteral( "rowid" ) ); // introduced by ogr provider
83 }
84 
86 {
88  return new QgsAuxiliaryLayer( mJoinInfo.targetFieldName(), mFileName, target->id(), target );
89 }
90 
92 {
93  bool rc = deleteFeatures( allFeatureIds() );
94  commitChanges();
95  startEditing();
96  return rc;
97 }
98 
100 {
101  QgsVectorLayer *layer = QgsMemoryProviderUtils::createMemoryLayer( QStringLiteral( "auxiliary_layer" ), fields(), mLayer->wkbType(), mLayer->crs() );
102 
103  QString pkField = mJoinInfo.targetFieldName();
104  QgsFeature joinFeature;
105  QgsFeature targetFeature;
107 
108  layer->startEditing();
109  while ( it.nextFeature( joinFeature ) )
110  {
111  QString filter = QgsExpression::createFieldEqualityExpression( pkField, joinFeature.attribute( AS_JOINFIELD ) );
112 
113  QgsFeatureRequest request;
114  request.setFilterExpression( filter );
115 
116  mLayer->getFeatures( request ).nextFeature( targetFeature );
117 
118  if ( targetFeature.isValid() )
119  {
120  QgsFeature newFeature( joinFeature );
121  newFeature.setGeometry( targetFeature.geometry() );
122  layer->addFeature( newFeature );
123  }
124  }
125  layer->commitChanges();
126 
127  return layer;
128 }
129 
131 {
132  return mJoinInfo;
133 }
134 
135 bool QgsAuxiliaryLayer::exists( const QgsPropertyDefinition &definition ) const
136 {
137  return ( indexOfPropertyDefinition( definition ) >= 0 );
138 }
139 
141 {
142  if ( ( definition.name().isEmpty() && definition.comment().isEmpty() ) || exists( definition ) )
143  return false;
144 
145  const QgsField af = createAuxiliaryField( definition );
146  const bool rc = addAttribute( af );
147  updateFields();
148  mLayer->updateFields();
149 
150  if ( rc )
151  {
152  int auxIndex = indexOfPropertyDefinition( definition );
153  int index = mLayer->fields().indexOf( nameFromProperty( definition, true ) );
154 
155  if ( index >= 0 && auxIndex >= 0 )
156  {
157  if ( isHiddenProperty( auxIndex ) )
158  {
159  // update editor widget
160  QgsEditorWidgetSetup setup = QgsEditorWidgetSetup( QStringLiteral( "Hidden" ), QVariantMap() );
161  setEditorWidgetSetup( auxIndex, setup );
162 
163  // column is hidden
164  QgsAttributeTableConfig attrCfg = mLayer->attributeTableConfig();
165  attrCfg.update( mLayer->fields() );
166  QVector<QgsAttributeTableConfig::ColumnConfig> columns = attrCfg.columns();
167  QVector<QgsAttributeTableConfig::ColumnConfig>::iterator it;
168 
169  for ( it = columns.begin(); it != columns.end(); ++it )
170  {
171  if ( it->name.compare( mLayer->fields().field( index ).name() ) == 0 )
172  it->hidden = true;
173  }
174 
175  attrCfg.setColumns( columns );
176  mLayer->setAttributeTableConfig( attrCfg );
177  }
178  else if ( definition.standardTemplate() == QgsPropertyDefinition::ColorNoAlpha
180  {
181  QgsEditorWidgetSetup setup = QgsEditorWidgetSetup( QStringLiteral( "Color" ), QVariantMap() );
182  setEditorWidgetSetup( auxIndex, setup );
183  }
184 
185  mLayer->setEditorWidgetSetup( index, editorWidgetSetup( auxIndex ) );
186  }
187  }
188 
189  return rc;
190 }
191 
193 {
194  QgsFields afields;
195 
196  for ( int i = 2; i < fields().count(); i++ ) // ignore rowid and PK field
197  afields.append( createAuxiliaryField( fields().field( i ) ) );
198 
199  return afields;
200 }
201 
203 {
205  bool rc = commitChanges();
206  startEditing();
207  return rc;
208 }
209 
211 {
212  bool rc = false;
213 
214  if ( isEditable() )
215  {
216  rc = commitChanges();
217  }
218 
219  startEditing();
220 
221  return rc;
222 }
223 
225 {
226  int index = -1;
227 
228  if ( layer && layer->labeling() && layer->auxiliaryLayer() )
229  {
230  // property definition are identical whatever the provider id
231  const QgsPropertyDefinition def = layer->labeling()->settings().propertyDefinitions()[property];
232  const QString fieldName = nameFromProperty( def, true );
233 
234  layer->auxiliaryLayer()->addAuxiliaryField( def );
235 
236  if ( layer->auxiliaryLayer()->indexOfPropertyDefinition( def ) >= 0 )
237  {
238  const QgsProperty prop = QgsProperty::fromField( fieldName );
239 
240  const QStringList subProviderIds = layer->labeling()->subProviders();
241  for ( const QString &providerId : subProviderIds )
242  {
243  QgsPalLayerSettings *settings = new QgsPalLayerSettings( layer->labeling()->settings( providerId ) );
244 
246  c.setProperty( property, prop );
247  settings->setDataDefinedProperties( c );
248 
249  layer->labeling()->setSettings( settings, providerId );
250  }
251  }
252 
253  index = layer->fields().lookupField( fieldName );
254  }
255 
256  return index;
257 }
258 
260 {
261  int index = -1;
262 
263  if ( layer && layer->diagramLayerSettings() && layer->auxiliaryLayer() )
264  {
265  const QgsPropertyDefinition def = layer->diagramLayerSettings()->propertyDefinitions()[property];
266 
267  if ( layer->auxiliaryLayer()->addAuxiliaryField( def ) )
268  {
269  const QString fieldName = nameFromProperty( def, true );
270  const QgsProperty prop = QgsProperty::fromField( fieldName );
271 
272  QgsDiagramLayerSettings settings( *layer->diagramLayerSettings() );
273 
275  c.setProperty( property, prop );
276  settings.setDataDefinedProperties( c );
277 
278  layer->setDiagramLayerSettings( settings );
279  index = layer->fields().lookupField( fieldName );
280  }
281  }
282 
283  return index;
284 }
285 
286 bool QgsAuxiliaryLayer::isHiddenProperty( int index ) const
287 {
288  bool hidden = false;
290 
291  if ( def.origin().compare( QLatin1String( "labeling" ) ) == 0 )
292  {
293  const PalPropertyList &palProps = *palHiddenProperties();
294  for ( const QgsPalLayerSettings::Property &p : palProps )
295  {
296  const QString propName = QgsPalLayerSettings::propertyDefinitions()[ p ].name();
297  if ( propName.compare( def.name() ) == 0 )
298  {
299  hidden = true;
300  break;
301  }
302  }
303  }
304 
305  return hidden;
306 }
307 
309 {
310  int p = -1;
312 
313  if ( aDef.origin().compare( QLatin1String( "labeling" ) ) == 0 )
314  {
316  QgsPropertiesDefinition::const_iterator it = defs.constBegin();
317  for ( ; it != defs.constEnd(); ++it )
318  {
319  if ( it->name().compare( aDef.name(), Qt::CaseInsensitive ) == 0 )
320  {
321  p = it.key();
322  break;
323  }
324  }
325  }
326  else if ( aDef.origin().compare( QLatin1String( "symbol" ) ) == 0 )
327  {
329  QgsPropertiesDefinition::const_iterator it = defs.constBegin();
330  for ( ; it != defs.constEnd(); ++it )
331  {
332  if ( it->name().compare( aDef.name(), Qt::CaseInsensitive ) == 0 )
333  {
334  p = it.key();
335  break;
336  }
337  }
338  }
339  else if ( aDef.origin().compare( QLatin1String( "diagram" ) ) == 0 )
340  {
342  QgsPropertiesDefinition::const_iterator it = defs.constBegin();
343  for ( ; it != defs.constEnd(); ++it )
344  {
345  if ( it->name().compare( aDef.name(), Qt::CaseInsensitive ) == 0 )
346  {
347  p = it.key();
348  break;
349  }
350  }
351  }
352 
353  return p;
354 }
355 
357 {
358  return propertyDefinitionFromField( fields().field( index ) );
359 }
360 
362 {
363  return fields().indexOf( nameFromProperty( def ) );
364 }
365 
367 {
368  QString fieldName = def.origin();
369 
370  if ( !def.name().isEmpty() )
371  fieldName = QStringLiteral( "%1_%2" ).arg( fieldName, def.name().toLower() );
372 
373  if ( !def.comment().isEmpty() )
374  fieldName = QStringLiteral( "%1_%2" ).arg( fieldName, def.comment() );
375 
376  if ( joined )
377  fieldName = QStringLiteral( "%1%2" ).arg( AS_JOINPREFIX, fieldName );
378 
379  return fieldName;
380 }
381 
383 {
384  QgsField afield;
385 
386  if ( !def.name().isEmpty() || !def.comment().isEmpty() )
387  {
388  QVariant::Type type = QVariant::Invalid;
389  QString typeName;
390  int len( 0 ), precision( 0 );
391  switch ( def.dataType() )
392  {
394  type = QVariant::String;
395  len = 50;
396  typeName = QStringLiteral( "String" );
397  break;
399  type = QVariant::Double;
400  len = 0;
401  precision = 0;
402  typeName = QStringLiteral( "Real" );
403  break;
405  type = QVariant::Int; // sqlite does not have a bool type
406  typeName = QStringLiteral( "Integer" );
407  break;
408  }
409 
410  afield.setType( type );
411  afield.setName( nameFromProperty( def ) );
412  afield.setTypeName( typeName );
413  afield.setLength( len );
414  afield.setPrecision( precision );
415  }
416 
417  return afield;
418 }
419 
421 {
423  const QStringList parts = f.name().split( '_' );
424 
425  if ( parts.size() <= 1 )
426  return def;
427 
428  const QString origin = parts[0];
429  const QString propertyName = parts[1];
430 
431  if ( origin.compare( QLatin1String( "labeling" ), Qt::CaseInsensitive ) == 0 )
432  {
434  for ( auto it = props.constBegin(); it != props.constEnd(); ++it )
435  {
436  if ( it.value().name().compare( propertyName, Qt::CaseInsensitive ) == 0 )
437  {
438  def = it.value();
439  if ( parts.size() >= 3 )
440  def.setComment( parts.mid( 2 ).join( '_' ) );
441  break;
442  }
443  }
444  }
445  else if ( origin.compare( QLatin1String( "symbol" ), Qt::CaseInsensitive ) == 0 )
446  {
448  for ( auto it = props.constBegin(); it != props.constEnd(); ++it )
449  {
450  if ( it.value().name().compare( propertyName, Qt::CaseInsensitive ) == 0 )
451  {
452  def = it.value();
453  if ( parts.size() >= 3 )
454  def.setComment( parts.mid( 2 ).join( '_' ) );
455  break;
456  }
457  }
458  }
459  else if ( origin.compare( QLatin1String( "diagram" ), Qt::CaseInsensitive ) == 0 )
460  {
462  for ( auto it = props.constBegin(); it != props.constEnd(); ++it )
463  {
464  if ( it.value().name().compare( propertyName, Qt::CaseInsensitive ) == 0 )
465  {
466  def = it.value();
467  if ( parts.size() >= 3 )
468  def.setComment( parts.mid( 2 ).join( '_' ) );
469  break;
470  }
471  }
472  }
473  else
474  {
475  def.setOrigin( origin );
476  def.setName( propertyName );
477  switch ( f.type() )
478  {
479  case QVariant::Double:
481  break;
482 
483  case QVariant::Bool:
485  break;
486 
487  case QVariant::String:
488  default:
490  break;
491  }
492 
493  if ( parts.size() >= 3 )
494  def.setComment( parts.mid( 2 ).join( '_' ) );
495  }
496 
497  return def;
498 }
499 
501 {
503  QgsField afield;
504 
505  if ( !def.name().isEmpty() || !def.comment().isEmpty() )
506  {
507  afield = createAuxiliaryField( def );
508  afield.setTypeName( field.typeName() );
509  }
510 
511  return afield;
512 }
513 
514 //
515 // QgsAuxiliaryStorage
516 //
517 
519  : mCopy( copy )
520 {
521  initTmpFileName();
522 
523  if ( !project.absoluteFilePath().isEmpty() )
524  {
525  mFileName = filenameForProject( project );
526  }
527 
528  open( mFileName );
529 }
530 
531 QgsAuxiliaryStorage::QgsAuxiliaryStorage( const QString &filename, bool copy )
532  : mFileName( filename )
533  , mCopy( copy )
534 {
535  initTmpFileName();
536 
537  open( filename );
538 }
539 
541 {
542  QFile::remove( mTmpFileName );
543 }
544 
546 {
547  return mValid;
548 }
549 
551 {
552  return mFileName;
553 }
554 
556 {
557  if ( mFileName.isEmpty() )
558  {
559  // only a saveAs is available on a new database
560  return false;
561  }
562  else if ( mCopy )
563  {
564  if ( QFile::exists( mFileName ) )
565  QFile::remove( mFileName );
566 
567  return QFile::copy( mTmpFileName, mFileName );
568  }
569  else
570  {
571  // if the file is not empty the copy mode is not activated, then we're
572  // directly working on the database since the beginning (no savepoints
573  // /rollback for now)
574  return true;
575  }
576 }
577 
579 {
580  QgsAuxiliaryLayer *alayer = nullptr;
581 
582  if ( mValid && layer )
583  {
584  const QString table( layer->id() );
586  database = openDB( currentFileName() );
587 
588  if ( !tableExists( table, database.get() ) )
589  {
590  if ( !createTable( field.typeName(), table, database.get() ) )
591  {
592  return alayer;
593  }
594  }
595 
596  alayer = new QgsAuxiliaryLayer( field.name(), currentFileName(), table, layer );
597  alayer->startEditing();
598  }
599 
600  return alayer;
601 }
602 
604 {
605  bool rc = false;
606  QgsDataSourceUri uri = parseOgrUri( ogrUri );
607 
608  if ( !uri.database().isEmpty() && !uri.table().isEmpty() )
609  {
611  database = openDB( uri.database() );
612 
613  if ( database )
614  {
615  QString sql = QStringLiteral( "DROP TABLE %1" ).arg( uri.table() );
616  rc = exec( sql, database.get() );
617 
618  sql = QStringLiteral( "VACUUM" );
619  rc = exec( sql, database.get() );
620  }
621  }
622 
623  return rc;
624 }
625 
626 bool QgsAuxiliaryStorage::duplicateTable( const QgsDataSourceUri &ogrUri, const QString &newTable )
627 {
628  QgsDataSourceUri uri = parseOgrUri( ogrUri );
629  bool rc = false;
630 
631  if ( !uri.table().isEmpty() && !uri.database().isEmpty() )
632  {
634  database = openDB( uri.database() );
635 
636  if ( database )
637  {
638  QString sql = QStringLiteral( "CREATE TABLE %1 AS SELECT * FROM %2" ).arg( newTable, uri.table() );
639  rc = exec( sql, database.get() );
640  }
641  }
642 
643  return rc;
644 }
645 
647 {
648  return mErrorString;
649 }
650 
651 bool QgsAuxiliaryStorage::saveAs( const QString &filename )
652 {
653  mErrorString.clear();
654 
655  QFile dest( filename );
656  if ( dest.exists() && !dest.remove() )
657  {
658  mErrorString = dest.errorString();
659  return false;
660  }
661 
662  QFile origin( currentFileName() );
663  if ( !origin.copy( filename ) )
664  {
665  mErrorString = origin.errorString();
666  return false;
667  }
668 
669  return true;
670 }
671 
673 {
674  return saveAs( filenameForProject( project ) );
675 }
676 
678 {
679  return AS_EXTENSION;
680 }
681 
683 {
684  const QFileInfo fileinfo( filenameForProject( project ) );
685  return fileinfo.exists() && fileinfo.isFile();
686 }
687 
688 bool QgsAuxiliaryStorage::exec( const QString &sql, sqlite3 *handler )
689 {
690  bool rc = false;
691 
692  if ( handler )
693  {
694  const int err = sqlite3_exec( handler, sql.toStdString().c_str(), nullptr, nullptr, nullptr );
695 
696  if ( err == SQLITE_OK )
697  rc = true;
698  else
699  debugMsg( sql, handler );
700  }
701 
702  return rc;
703 }
704 
705 void QgsAuxiliaryStorage::debugMsg( const QString &sql, sqlite3 *handler )
706 {
707 #ifdef QGISDEBUG
708  const QString err = QString::fromUtf8( sqlite3_errmsg( handler ) );
709  const QString msg = QObject::tr( "Unable to execute" );
710  const QString errMsg = QObject::tr( "%1 '%2': %3" ).arg( msg, sql, err );
711  QgsDebugMsg( errMsg );
712 #else
713  Q_UNUSED( sql )
714  Q_UNUSED( handler )
715 #endif
716 }
717 
718 bool QgsAuxiliaryStorage::createTable( const QString &type, const QString &table, sqlite3 *handler )
719 {
720  const QString sql = QStringLiteral( "CREATE TABLE IF NOT EXISTS '%1' ( '%2' %3 )" ).arg( table, AS_JOINFIELD, type );
721 
722  if ( !exec( sql, handler ) )
723  return false;
724 
725  return true;
726 }
727 
728 spatialite_database_unique_ptr QgsAuxiliaryStorage::createDB( const QString &filename )
729 {
731 
732  int rc;
733  rc = database.open_v2( filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr );
734  if ( rc )
735  {
736  debugMsg( QStringLiteral( "sqlite3_open_v2" ), database.get() );
737  }
738  else
739  // activating Foreign Key constraints
740  exec( QStringLiteral( "PRAGMA foreign_keys = 1" ), database.get() );
741 
742  return database;
743 }
744 
745 spatialite_database_unique_ptr QgsAuxiliaryStorage::openDB( const QString &filename )
746 {
748  int rc = database.open_v2( filename, SQLITE_OPEN_READWRITE, nullptr );
749 
750  if ( rc )
751  {
752  debugMsg( QStringLiteral( "sqlite3_open_v2" ), database.get() );
753  }
754 
755  return database;
756 }
757 
758 bool QgsAuxiliaryStorage::tableExists( const QString &table, sqlite3 *handler )
759 {
760  const QString sql = QStringLiteral( "SELECT 1 FROM sqlite_master WHERE type='table' AND name='%1'" ).arg( table );
761  int rows = 0;
762  int columns = 0;
763  char **results = nullptr;
764  const int rc = sqlite3_get_table( handler, sql.toStdString().c_str(), &results, &rows, &columns, nullptr );
765  if ( rc != SQLITE_OK )
766  {
767  debugMsg( sql, handler );
768  return false;
769  }
770 
771  sqlite3_free_table( results );
772  if ( rows >= 1 )
773  return true;
774 
775  return false;
776 }
777 
778 spatialite_database_unique_ptr QgsAuxiliaryStorage::open( const QString &filename )
779 {
781 
782  if ( filename.isEmpty() )
783  {
784  if ( ( database = createDB( currentFileName() ) ) )
785  mValid = true;
786  }
787  else if ( QFile::exists( filename ) )
788  {
789  if ( mCopy )
790  QFile::copy( filename, mTmpFileName );
791 
792  if ( ( database = openDB( currentFileName() ) ) )
793  mValid = true;
794  }
795  else
796  {
797  if ( ( database = createDB( currentFileName() ) ) )
798  mValid = true;
799  }
800 
801  return database;
802 }
803 
804 spatialite_database_unique_ptr QgsAuxiliaryStorage::open( const QgsProject &project )
805 {
806  return open( filenameForProject( project ) );
807 }
808 
809 QString QgsAuxiliaryStorage::filenameForProject( const QgsProject &project )
810 {
811  const QFileInfo info( project.absoluteFilePath() );
812  const QString path = info.path() + QDir::separator() + info.baseName();
813  return path + '.' + QgsAuxiliaryStorage::extension();
814 }
815 
816 void QgsAuxiliaryStorage::initTmpFileName()
817 {
818  QTemporaryFile tmpFile;
819  tmpFile.open();
820  tmpFile.close();
821  mTmpFileName = tmpFile.fileName();
822 }
823 
825 {
826  if ( mCopy || mFileName.isEmpty() )
827  return mTmpFileName;
828  else
829  return mFileName;
830 }
831 
832 QgsDataSourceUri QgsAuxiliaryStorage::parseOgrUri( const QgsDataSourceUri &uri )
833 {
834  QgsDataSourceUri newUri;
835 
836  // parsing for ogr style uri :
837  // " filePath|layername='tableName' table="" sql="
838  QStringList uriParts = uri.uri().split( '|' );
839  if ( uriParts.count() < 2 )
840  return newUri;
841 
842  const QString databasePath = uriParts[0].replace( ' ', QString() );
843 
844  const QString table = uriParts[1];
845  QStringList tableParts = table.split( ' ' );
846 
847  if ( tableParts.count() < 1 )
848  return newUri;
849 
850  const QString tableName = tableParts[0].replace( QLatin1String( "layername=" ), QString() );
851 
852  newUri.setDataSource( QString(), tableName, QString() );
853  newUri.setDatabase( databasePath );
854 
855  return newUri;
856 }
virtual QStringList subProviders() const
Gets list of sub-providers within the layer's labeling.
virtual void setSettings(QgsPalLayerSettings *settings, const QString &providerId=QString())=0
Set pal settings for a specific provider (takes ownership).
virtual QgsPalLayerSettings settings(const QString &providerId=QString()) const =0
Gets associated label settings.
This is a container for configuration of the attribute table.
QVector< QgsAttributeTableConfig::ColumnConfig > columns() const
Gets the list with all columns and their configuration.
void update(const QgsFields &fields)
Update the configuration with the given fields.
void setColumns(const QVector< QgsAttributeTableConfig::ColumnConfig > &columns)
Set the list of columns visible in the attribute table.
Class allowing to manage the auxiliary storage for a vector layer.
static QgsPropertyDefinition propertyDefinitionFromField(const QgsField &field)
Returns the property definition from an auxiliary field.
static int createProperty(QgsPalLayerSettings::Property property, QgsVectorLayer *vlayer)
Creates if necessary a new auxiliary field for a PAL property and activates this property in settings...
bool clear()
Deletes all features from the layer.
bool addAuxiliaryField(const QgsPropertyDefinition &definition)
Adds an auxiliary field for the given property.
bool isHiddenProperty(int index) const
Returns true if the underlying field has to be hidden from editing tools like attribute table,...
QgsVectorLayer * toSpatialLayer() const
An auxiliary layer is not spatial.
bool deleteAttribute(int attr) override
Removes attribute from the layer and commits changes.
QgsFields auxiliaryFields() const
Returns a list of all auxiliary fields currently managed by the layer.
QgsAuxiliaryLayer(const QString &pkField, const QString &filename, const QString &table, QgsVectorLayer *vlayer)
Constructor.
bool save()
Commits changes and starts editing then.
int propertyFromIndex(int index) const
Returns the underlying property key for the field index.
QgsVectorLayerJoinInfo joinInfo() const
Returns information to use for joining with primary key and so on.
static QString nameFromProperty(const QgsPropertyDefinition &def, bool joined=false)
Returns the name of the auxiliary field for a property definition.
QgsPropertyDefinition propertyDefinitionFromIndex(int index) const
Returns the property definition for the underlying field index.
bool exists(const QgsPropertyDefinition &definition) const
Returns true if the property is stored in the layer already, false otherwise.
int indexOfPropertyDefinition(const QgsPropertyDefinition &definition) const
Returns the index of the auxiliary field for a specific property definition.
static QgsField createAuxiliaryField(const QgsPropertyDefinition &definition)
Creates a new auxiliary field from a property definition.
virtual ~QgsAuxiliaryStorage()
Destructor.
static bool duplicateTable(const QgsDataSourceUri &uri, const QString &newTable)
Duplicates a table and its content.
QString errorString() const
Returns the underlying error string describing potential errors happening in saveAs().
bool save() const
Saves the current database.
static bool exists(const QgsProject &project)
Returns true if the auxiliary database yet exists for a project, false otherwise.
static bool deleteTable(const QgsDataSourceUri &uri)
Removes a table from the auxiliary storage.
QgsAuxiliaryLayer * createAuxiliaryLayer(const QgsField &field, QgsVectorLayer *layer) const
Creates an auxiliary layer for a vector layer.
bool saveAs(const QString &filename)
Saves the current database to a new path.
bool isValid() const
Returns the status of the auxiliary storage currently defined.
QString currentFileName() const
Returns the path of the current database used.
QgsAuxiliaryStorage(const QgsProject &project, bool copy=true)
Constructor.
QString fileName() const
Returns the target filename of the database.
static QString extension()
Returns the extension used for auxiliary databases.
Class for storing the component parts of a RDBMS data source URI (e.g.
QString table() const
Returns the table name stored in the URI.
QString uri(bool expandAuthConfig=true) const
Returns the complete URI as a string.
void setDataSource(const QString &aSchema, const QString &aTable, const QString &aGeometryColumn, const QString &aSql=QString(), const QString &aKeyColumn=QString())
Sets all data source related members at once.
QString database() const
Returns the database name stored in the URI.
void setDatabase(const QString &database)
Sets the URI database name.
Stores the settings for rendering of all diagrams for a layer.
Property
Data definable properties.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the diagram property definitions.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the diagram's property collection, used for data defined overrides.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the diagram's property collection, used for data defined overrides.
Holder for the widget type and its configuration for a field.
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value)
Create an expression allowing to evaluate if a field is equal to a value.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
virtual QgsFeatureIds allFeatureIds() const
Returns a list of all feature IDs for features present in the source.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsGeometry geometry
Definition: qgsfeature.h:67
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:190
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:287
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:144
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:51
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:138
QString name
Definition: qgsfield.h:60
void setPrecision(int precision)
Set the field precision.
Definition: qgsfield.cpp:198
void setName(const QString &name)
Set the field name.
Definition: qgsfield.cpp:174
void setLength(int len)
Set the field length.
Definition: qgsfield.cpp:194
QVariant::Type type
Definition: qgsfield.h:58
void setType(QVariant::Type type)
Set variant type.
Definition: qgsfield.cpp:179
void setTypeName(const QString &typeName)
Set the field type.
Definition: qgsfield.cpp:189
Container of fields for a vector layer.
Definition: qgsfields.h:45
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
Definition: qgsfields.cpp:59
int indexOf(const QString &fieldName) const
Gets the field index from the field name.
Definition: qgsfields.cpp:207
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
QgsField field(int fieldIdx) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:168
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:344
QString source() const
Returns the source for the layer.
QgsMapLayerType type
Definition: qgsmaplayer.h:92
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:91
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
static QgsVectorLayer * createMemoryLayer(const QString &name, const QgsFields &fields, QgsWkbTypes::Type geometryType=QgsWkbTypes::NoGeometry, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Creates a new memory layer using the specified parameters.
Contains settings for how a map layer will be labeled.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the label's property collection, used for data defined overrides.
Property
Data definable properties.
@ LabelRotation
Label rotation.
@ PositionY
Y-coordinate data defined label position.
@ Strikeout
Use strikeout.
@ FontStyle
Font style name.
@ PositionX
X-coordinate data defined label position.
@ CalloutDraw
Show callout.
@ Underline
Use underline.
@ Bold
Use bold style.
@ MaxScale
Max scale (deprecated, for old project compatibility only)
@ Hali
Horizontal alignment for data defined label position (Left, Center, Right)
@ LabelAllParts
Whether all parts of multi-part features should be labeled.
@ Italic
Use italic style.
@ MinScale
Min scale (deprecated, for old project compatibility only)
@ Family
Font family.
@ Vali
Vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top)
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the label's property collection, used for data defined overrides.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the labeling property definitions.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:99
QString absoluteFilePath() const
Returns full absolute path to the project file if the project is stored in a file system - derived fr...
Definition: qgsproject.cpp:729
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
Definition for a property.
Definition: qgsproperty.h:48
StandardPropertyTemplate standardTemplate() const
Returns the property's standard template, if applicable.
Definition: qgsproperty.h:195
QString comment() const
Returns the comment of the property.
Definition: qgsproperty.h:169
DataType dataType() const
Returns the allowable field/value data type for the property.
Definition: qgsproperty.h:189
void setOrigin(const QString &origin)
Sets the origin of the property.
Definition: qgsproperty.h:159
@ ColorNoAlpha
Color with no alpha channel.
Definition: qgsproperty.h:66
@ ColorWithAlpha
Color with alpha channel.
Definition: qgsproperty.h:65
QString name() const
Returns the name of the property.
Definition: qgsproperty.h:140
void setDataType(DataType type)
Sets the data type.
Definition: qgsproperty.h:184
void setName(const QString &name)
Sets the name of the property.
Definition: qgsproperty.h:145
QString origin() const
Returns the origin of the property.
Definition: qgsproperty.h:152
void setComment(const QString &comment)
Sets comment of the property.
Definition: qgsproperty.h:174
@ DataTypeString
Property requires a string value.
Definition: qgsproperty.h:93
@ DataTypeBoolean
Property requires a boolean value.
Definition: qgsproperty.h:107
@ DataTypeNumeric
Property requires a numeric value.
Definition: qgsproperty.h:100
A store for object properties.
Definition: qgsproperty.h:232
static QgsProperty fromField(const QString &fieldName, bool isActive=true)
Returns a new FieldBasedProperty created from the specified field name.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the symbol layer property definitions.
Defines left outer join from our vector layer to some other vector layer.
QString targetFieldName() const
Returns name of the field of our layer that will be used for join.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
Q_INVOKABLE bool startEditing()
Makes the layer editable.
bool addAttribute(const QgsField &field)
Add an attribute field (but does not commit it) returns true if the field was added.
void updateFields()
Will regenerate the fields property of this layer by obtaining all fields from the dataProvider,...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
bool deleteFeatures(const QgsFeatureIds &fids, DeleteContext *context=nullptr)
Deletes a set of features from the layer (but does not commit it)
const QgsDiagramLayerSettings * diagramLayerSettings() const
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
virtual bool deleteAttribute(int attr)
Deletes an attribute field (but does not commit it).
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
void setEditorWidgetSetup(int index, const QgsEditorWidgetSetup &setup)
The editor widget setup defines which QgsFieldFormatter and editor widget will be used for the field ...
Q_INVOKABLE bool commitChanges(bool stopEditing=true)
Attempts to commit to the underlying data provider any buffered changes made since the last to call t...
QgsEditorWidgetSetup editorWidgetSetup(int index) const
The editor widget setup defines which QgsFieldFormatter and editor widget will be used for the field ...
QgsVectorLayer * clone() const override
Returns a new instance equivalent to this one.
QgsAttributeTableConfig attributeTableConfig() const
Returns the attribute table configuration object.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) FINAL
Adds a single feature to the sink.
void setAttributeTableConfig(const QgsAttributeTableConfig &attributeTableConfig)
Sets the attribute table configuration object.
void setDiagramLayerSettings(const QgsDiagramLayerSettings &s)
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
Unique pointer for spatialite databases, which automatically closes the database when the pointer goe...
int open_v2(const QString &path, int flags, const char *zVfs)
Opens the database at the specified file path.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#define AS_JOINFIELD
Q_GLOBAL_STATIC_WITH_ARGS(PalPropertyList, palHiddenProperties,({ QgsPalLayerSettings::PositionX, QgsPalLayerSettings::PositionY, QgsPalLayerSettings::Show, QgsPalLayerSettings::LabelRotation, QgsPalLayerSettings::Family, QgsPalLayerSettings::FontStyle, QgsPalLayerSettings::Size, QgsPalLayerSettings::Bold, QgsPalLayerSettings::Italic, QgsPalLayerSettings::Underline, QgsPalLayerSettings::Color, QgsPalLayerSettings::Strikeout, QgsPalLayerSettings::MultiLineAlignment, QgsPalLayerSettings::BufferSize, QgsPalLayerSettings::BufferDraw, QgsPalLayerSettings::BufferColor, QgsPalLayerSettings::LabelDistance, QgsPalLayerSettings::Hali, QgsPalLayerSettings::Vali, QgsPalLayerSettings::ScaleVisibility, QgsPalLayerSettings::MinScale, QgsPalLayerSettings::MaxScale, QgsPalLayerSettings::AlwaysShow, QgsPalLayerSettings::CalloutDraw, QgsPalLayerSettings::LabelAllParts })) QgsAuxiliaryLayer
QVector< QgsPalLayerSettings::Property > PalPropertyList
#define AS_JOINPREFIX
#define AS_EXTENSION
struct sqlite3 sqlite3
const QgsField & field
Definition: qgsfield.h:472
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
const QString & typeName
int precision