QGIS API Documentation  3.12.1-BucureČ™ti (121cc00ff0)
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 : [email protected]
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.setJoinFieldNamesBlackList( 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 
274  QgsPropertyCollection c = settings.dataDefinedProperties();
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( QStringLiteral( "layername=" ), QString() );
851 
852  newUri.setDataSource( QString(), tableName, QString() );
853  newUri.setDatabase( databasePath );
854 
855  return newUri;
856 }
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
int lookupField(const QString &fieldName) const
Looks up field&#39;s index from the field name.
Definition: qgsfields.cpp:324
#define AS_JOINPREFIX
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:183
void updateFields()
Will regenerate the fields property of this layer by obtaining all fields from the dataProvider...
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the labeling property definitions.
Wrapper for iterator of features from vector data provider or vector layer.
static QgsField createAuxiliaryField(const QgsPropertyDefinition &definition)
Creates a new auxiliary field from a property definition.
int precision
int open_v2(const QString &path, int flags, const char *zVfs)
Opens the database at the specified file path.
QString targetFieldName() const
Returns name of the field of our layer that will be used for join.
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
void setDiagramLayerSettings(const QgsDiagramLayerSettings &s)
QString table() const
Returns the table name stored in the URI.
void update(const QgsFields &fields)
Update the configuration with the given fields.
Property
Data definable properties.
bool isValid() const
Returns the status of the auxiliary storage currently defined.
QgsMapLayerType type() const
Returns the type of the layer.
QString name
Definition: qgsfield.h:59
bool save()
Commits changes and starts editing then.
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 propertyFromIndex(int index) const
Returns the underlying property key for the field index.
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
void setPrecision(int precision)
Set the field precision.
Definition: qgsfield.cpp:176
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QVector< QgsPalLayerSettings::Property > PalPropertyList
Class allowing to manage the auxiliary storage for a vector layer.
Q_INVOKABLE bool commitChanges()
Attempts to commit to the underlying data provider any buffered changes made since the last to call t...
int indexOfPropertyDefinition(const QgsPropertyDefinition &definition) const
Returns the index of the auxiliary field for a specific property definition.
Q_INVOKABLE bool startEditing()
Makes the layer editable.
virtual void setSettings(QgsPalLayerSettings *settings, const QString &providerId=QString())=0
Set pal settings for a specific provider (takes ownership).
static QgsProperty fromField(const QString &fieldName, bool isActive=true)
Returns a new FieldBasedProperty created from the specified field name.
bool deleteFeatures(const QgsFeatureIds &fids)
Deletes a set of features from the layer (but does not commit it)
X-coordinate data defined label position.
Min scale (deprecated, for old project compatibility only)
Container of fields for a vector layer.
Definition: qgsfields.h:42
void setName(const QString &name)
Set the field name.
Definition: qgsfield.cpp:152
Color with alpha channel.
Definition: qgsproperty.h:64
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
QString currentFileName() const
Returns the path of the current database used.
QgsVectorLayer * toSpatialLayer() const
An auxiliary layer is not spatial.
void setName(const QString &name)
Sets the name of the property.
Definition: qgsproperty.h:143
#define AS_EXTENSION
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
static QString extension()
Returns the extension used for auxiliary databases.
#define AS_JOINFIELD
virtual QStringList subProviders() const
Gets list of sub-providers within the layer&#39;s labeling.
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
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...
void setLength(int len)
Set the field length.
Definition: qgsfield.cpp:172
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
bool save() const
Saves the current database.
Property
Data definable properties.
void setEditorWidgetSetup(int index, const QgsEditorWidgetSetup &setup)
The editor widget setup defines which QgsFieldFormatter and editor widget will be used for the field ...
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QString id() const
Returns the layer&#39;s unique ID, which is used to access this layer from QgsProject.
DataType dataType() const
Returns the allowable field/value data type for the property.
Definition: qgsproperty.h:187
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Unique pointer for spatialite databases, which automatically closes the database when the pointer goe...
QString fileName() const
Returns the target filename of the database.
virtual QgsPalLayerSettings settings(const QString &providerId=QString()) const =0
Gets associated label settings.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the label&#39;s property collection, used for data defined overrides.
Property requires a boolean value.
Definition: qgsproperty.h:105
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:116
void setTypeName(const QString &typeName)
Set the field type.
Definition: qgsfield.cpp:167
const QString & typeName
Defines left outer join from our vector layer to some other vector layer.
virtual bool deleteAttribute(int attr)
Deletes an attribute field (but does not commit it).
virtual ~QgsAuxiliaryStorage()
Destructor.
Horizontal alignment for data defined label position (Left, Center, Right)
Property requires a numeric value.
Definition: qgsproperty.h:98
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QgsVectorLayerJoinInfo joinInfo() const
Returns information to use for joining with primary key and so on.
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
Encapsulates a QGIS project, including sets of map layers and their styles, layouts, annotations, canvases, etc.
Definition: qgsproject.h:91
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:49
bool clear()
Deletes all features from the layer.
QgsAuxiliaryLayer(const QString &pkField, const QString &filename, const QString &table, QgsVectorLayer *vlayer)
Constructor.
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
A store for object properties.
Definition: qgsproperty.h:229
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value)
Create an expression allowing to evaluate if a field is equal to a value.
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
static bool deleteTable(const QgsDataSourceUri &uri)
Removes a table from the auxiliary storage.
void setDataType(DataType type)
Sets the data type.
Definition: qgsproperty.h:182
Definition for a property.
Definition: qgsproperty.h:46
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
struct sqlite3 sqlite3
QString uri(bool expandAuthConfig=true) const
Returns the complete URI as a string.
static bool exists(const QgsProject &project)
Returns true if the auxiliary database yet exists for a project, false otherwise. ...
Stores the settings for rendering of all diagrams for a layer.
QVector< QgsAttributeTableConfig::ColumnConfig > columns() const
Gets the list with all columns and their configuration.
QgsAttributeTableConfig attributeTableConfig() const
Returns the attribute table configuration object.
QString comment() const
Returns the comment of the property.
Definition: qgsproperty.h:167
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.
void setType(QVariant::Type type)
Set variant type.
Definition: qgsfield.cpp:157
QgsEditorWidgetSetup editorWidgetSetup(int index) const
The editor widget setup defines which QgsFieldFormatter and editor widget will be used for the field ...
void setColumns(const QVector< QgsAttributeTableConfig::ColumnConfig > &columns)
Set the list of columns visible in the attribute table.
int indexOf(const QString &fieldName) const
Gets the field index from the field name.
Definition: qgsfields.cpp:207
Property requires a string value.
Definition: qgsproperty.h:91
QString source() const
Returns the source for the layer.
QgsAuxiliaryStorage(const QgsProject &project, bool copy=true)
Constructor.
const QgsDiagramLayerSettings * diagramLayerSettings() const
Holder for the widget type and its configuration for a field.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the diagram property definitions.
void setOrigin(const QString &origin)
Sets the origin of the property.
Definition: qgsproperty.h:157
static QString nameFromProperty(const QgsPropertyDefinition &def, bool joined=false)
Returns the name of the auxiliary field for a property definition.
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:137
void setComment(const QString &comment)
Sets comment of the property.
Definition: qgsproperty.h:172
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr) FINAL
Adds a single feature to the sink.
QString errorString() const
Returns the underlying error string describing potential errors happening in saveAs().
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
bool deleteAttribute(int attr) override
Removes attribute from the layer and commits changes.
QgsGeometry geometry
Definition: qgsfeature.h:67
static bool duplicateTable(const QgsDataSourceUri &uri, const QString &newTable)
Duplicates a table and its content.
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.
QgsFields auxiliaryFields() const
Returns a list of all auxiliary fields currently managed by the layer.
Y-coordinate data defined label position.
bool nextFeature(QgsFeature &f)
This is a container for configuration of the attribute table.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the symbol layer property definitions.
Max scale (deprecated, for old project compatibility only)
Class for storing the component parts of a RDBMS data source URI (e.g.
bool addAuxiliaryField(const QgsPropertyDefinition &definition)
Adds an auxiliary field for the given property.
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:648
static QgsPropertyDefinition propertyDefinitionFromField(const QgsField &field)
Returns the property definition from an auxiliary field.
QString name() const
Returns the name of the property.
Definition: qgsproperty.h:138
Represents a vector layer which manages a vector based data sets.
bool addAttribute(const QgsField &field)
Add an attribute field (but does not commit it) returns true if the field was added.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:262
virtual QgsFeatureIds allFeatureIds() const
Returns a list of all feature IDs for features present in the source.
Vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top) ...
Whether all parts of multi-part features should be labeled.
void setAttributeTableConfig(const QgsAttributeTableConfig &attributeTableConfig)
Sets the attribute table configuration object.
QgsField field(int fieldIdx) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:168
bool isHiddenProperty(int index) const
Returns true if the underlying field has to be hidden from editing tools like attribute table...
QString database() const
Returns the database name stored in the URI.
QgsAuxiliaryLayer * createAuxiliaryLayer(const QgsField &field, QgsVectorLayer *layer) const
Creates an auxiliary layer for a vector layer.
QVariant::Type type
Definition: qgsfield.h:57
bool saveAs(const QString &filename)
Saves the current database to a new path.
void setDatabase(const QString &database)
Sets the URI database name.
QString origin() const
Returns the origin of the property.
Definition: qgsproperty.h:150
StandardPropertyTemplate standardTemplate() const
Returns the property&#39;s standard template, if applicable.
Definition: qgsproperty.h:193
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:86
QgsVectorLayer * clone() const override
Returns a new instance equivalent to this one.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the label&#39;s property collection, used for data defined overrides.
Color with no alpha channel.
Definition: qgsproperty.h:65