31 #include <QDomDocument>
34 #include <QMessageBox>
39 #include <spatialite.h>
46 #define CUSTOM_PROPERTY_IS_OFFLINE_EDITABLE "isOfflineEditable"
47 #define CUSTOM_PROPERTY_REMOTE_SOURCE "remoteSource"
48 #define CUSTOM_PROPERTY_REMOTE_PROVIDER "remoteProvider"
49 #define PROJECT_ENTRY_SCOPE_OFFLINE "OfflineEditingPlugin"
50 #define PROJECT_ENTRY_KEY_OFFLINE_DB_PATH "/OfflineDbPath"
67 if ( layerIds.isEmpty() )
71 QString dbPath = QDir( offlineDataPath ).absoluteFilePath( offlineDbFile );
76 int rc = sqlite3_open( dbPath.toUtf8().constData(), &db );
77 if ( rc != SQLITE_OK )
79 showWarning(
tr(
"Could not open the spatialite database" ) );
89 for (
int i = 0; i < layerIds.count(); i++ )
103 if ( projectTitle.isEmpty() )
107 projectTitle +=
" (offline)";
147 QList<QgsMapLayer*> offlineLayers;
149 for ( QMap<QString, QgsMapLayer*>::iterator layer_it = mapLayers.begin() ; layer_it != mapLayers.end(); ++layer_it )
154 offlineLayers << layer;
158 for (
int l = 0; l < offlineLayers.count(); l++ )
166 QString remoteName = layer->
name();
167 remoteName.remove( QRegExp(
" \\(offline\\)$" ) );
181 QList<QgsMapLayer *>() << remoteLayer,
true );
184 QString qgisLayerId = layer->
id();
185 QString sql = QString(
"SELECT \"id\" FROM 'log_layer_ids' WHERE \"qgis_id\" = '%1'" ).arg( qgisLayerId );
193 for (
int i = 0; i < commitNo; i++ )
210 sql = QString(
"DELETE FROM 'log_added_attrs' WHERE \"layer_id\" = %1" ).arg( layerId );
212 sql = QString(
"DELETE FROM 'log_added_features' WHERE \"layer_id\" = %1" ).arg( layerId );
214 sql = QString(
"DELETE FROM 'log_removed_features' WHERE \"layer_id\" = %1" ).arg( layerId );
216 sql = QString(
"DELETE FROM 'log_feature_updates' WHERE \"layer_id\" = %1" ).arg( layerId );
218 sql = QString(
"DELETE FROM 'log_geometry_updates' WHERE \"layer_id\" = %1" ).arg( layerId );
222 QString sql = QString(
"UPDATE 'log_indices' SET 'last_index' = 0 WHERE \"name\" = 'commit_no'" );
233 ( QStringList() << qgisLayerId ) );
237 projectTitle.remove( QRegExp(
" \\(offline\\)$" ) );
252 if ( !sqlite_handle )
257 int ret = sqlite3_get_table( sqlite_handle,
"select count(*) from sqlite_master", &results, &rows, &columns, NULL );
258 if ( ret != SQLITE_OK )
263 for (
int i = 1; i <= rows; i++ )
264 count = atoi( results[( i * columns ) + 0] );
267 sqlite3_free_table( results );
272 bool above41 =
false;
273 ret = sqlite3_get_table( sqlite_handle,
"select spatialite_version()", &results, &rows, &columns, NULL );
274 if ( ret == SQLITE_OK && rows == 1 && columns == 1 )
276 QString version = QString::fromUtf8( results[1] );
277 QStringList parts = version.split(
" ", QString::SkipEmptyParts );
278 if ( parts.size() >= 1 )
280 QStringList verparts = parts[0].split(
".", QString::SkipEmptyParts );
281 above41 = verparts.size() >= 2 && ( verparts[0].toInt() > 4 || ( verparts[0].toInt() == 4 && verparts[1].toInt() >= 1 ) );
285 sqlite3_free_table( results );
289 ret = sqlite3_exec( sqlite_handle, above41 ?
"SELECT InitSpatialMetadata(1)" :
"SELECT InitSpatialMetadata()", NULL, NULL, &errMsg );
291 if ( ret != SQLITE_OK )
293 QString errCause =
tr(
"Unable to initialize SpatialMetadata:\n" );
294 errCause += QString::fromUtf8( errMsg );
296 sqlite3_free( errMsg );
299 spatial_ref_sys_init( sqlite_handle, 0 );
307 QFile newDb( offlineDbPath );
308 if ( newDb.exists() )
310 QFile::remove( offlineDbPath );
315 QFileInfo fullPath = QFileInfo( offlineDbPath );
316 QDir path = fullPath.dir();
319 QDir().mkpath( path.absolutePath( ) );
322 QString dbPath = newDb.fileName();
323 spatialite_init( 0 );
324 ret = sqlite3_open_v2( dbPath.toUtf8().constData(), &sqlite_handle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL );
328 QString errCause =
tr(
"Could not create a new database\n" );
329 errCause += QString::fromUtf8( sqlite3_errmsg( sqlite_handle ) );
330 sqlite3_close( sqlite_handle );
335 ret = sqlite3_exec( sqlite_handle,
"PRAGMA foreign_keys = 1", NULL, 0, &errMsg );
336 if ( ret != SQLITE_OK )
338 showWarning(
tr(
"Unable to activate FOREIGN_KEY constraints" ) );
339 sqlite3_free( errMsg );
340 sqlite3_close( sqlite_handle );
346 sqlite3_close( sqlite_handle );
354 QString sql =
"CREATE TABLE 'log_indices' ('name' TEXT, 'last_index' INTEGER)";
357 sql =
"INSERT INTO 'log_indices' VALUES ('commit_no', 0)";
360 sql =
"INSERT INTO 'log_indices' VALUES ('layer_id', 0)";
364 sql =
"CREATE TABLE 'log_layer_ids' ('id' INTEGER, 'qgis_id' TEXT)";
368 sql =
"CREATE TABLE 'log_fids' ('layer_id' INTEGER, 'offline_fid' INTEGER, 'remote_fid' INTEGER)";
372 sql =
"CREATE TABLE 'log_added_attrs' ('layer_id' INTEGER, 'commit_no' INTEGER, ";
373 sql +=
"'name' TEXT, 'type' INTEGER, 'length' INTEGER, 'precision' INTEGER, 'comment' TEXT)";
377 sql =
"CREATE TABLE 'log_added_features' ('layer_id' INTEGER, 'fid' INTEGER)";
381 sql =
"CREATE TABLE 'log_removed_features' ('layer_id' INTEGER, 'fid' INTEGER)";
385 sql =
"CREATE TABLE 'log_feature_updates' ('layer_id' INTEGER, 'commit_no' INTEGER, 'fid' INTEGER, 'attr' INTEGER, 'value' TEXT)";
389 sql =
"CREATE TABLE 'log_geometry_updates' ('layer_id' INTEGER, 'commit_no' INTEGER, 'fid' INTEGER, 'geom_wkt' TEXT)";
404 QString tableName = layer->
name();
407 QString sql = QString(
"CREATE TABLE '%1' (" ).arg( tableName );
410 for (
int idx = 0; idx < fields.
count(); ++idx )
412 QString dataType =
"";
413 QVariant::Type type = fields[idx].type();
414 if ( type == QVariant::Int || type == QVariant::LongLong )
416 dataType =
"INTEGER";
418 else if ( type == QVariant::Double )
422 else if ( type == QVariant::String )
431 sql += delim + QString(
"'%1' %2" ).arg( fields[idx].name() ).arg( dataType );
437 QString geomType =
"";
444 geomType =
"MULTIPOINT";
447 geomType =
"LINESTRING";
450 geomType =
"MULTILINESTRING";
453 geomType =
"POLYGON";
456 geomType =
"MULTIPOLYGON";
462 QString sqlAddGeom = QString(
"SELECT AddGeometryColumn('%1', 'Geometry', %2, '%3', 2)" )
464 .arg( layer->
crs().
authid().startsWith(
"EPSG:", Qt::CaseInsensitive ) ? layer->
crs().
authid().mid( 5 ).toLong() : 0 )
468 QString sqlCreateIndex = QString(
"SELECT CreateSpatialIndex('%1', 'Geometry')" ).arg( tableName );
471 if ( rc == SQLITE_OK )
473 rc =
sqlExec( db, sqlAddGeom );
474 if ( rc == SQLITE_OK )
476 rc =
sqlExec( db, sqlCreateIndex );
480 if ( rc == SQLITE_OK )
484 .arg( offlineDbPath ).arg( tableName ), tableName +
" (offline)",
"spatialite" );
504 QList<QgsMapLayer *>() << newLayer );
524 int featureCount = 1;
526 QList<QgsFeatureId> remoteFeatureIds;
529 remoteFeatureIds << f.
id();
536 for (
int it = 0; it < attrs.count(); ++it )
538 newAttrs[column++] = attrs[it];
553 QList<QgsFeatureId> offlineFeatureIds;
558 offlineFeatureIds << f.
id();
563 int remoteCount = remoteFeatureIds.size();
564 for (
int i = 0; i < remoteCount; i++ )
566 addFidLookup( db, layerId, offlineFeatureIds.at( i ), remoteFeatureIds.at( remoteCount - ( i + 1 ) ) );
578 QStringList() << layer->
id() );
585 QString sql = QString(
"SELECT \"name\", \"type\", \"length\", \"precision\", \"comment\" FROM 'log_added_attrs' WHERE \"layer_id\" = %1 AND \"commit_no\" = %2" ).arg( layerId ).arg( commitNo );
589 QList<QgsVectorDataProvider::NativeType> nativeTypes = provider->
nativeTypes();
592 QMap < QVariant::Type, QString > typeNameLookup;
593 for (
int i = 0; i < nativeTypes.size(); i++ )
601 for (
int i = 0; i < fields.size(); i++ )
605 if ( typeNameLookup.contains( field.
type() ) )
607 QString typeName = typeNameLookup[ field.
type()];
613 showWarning( QString(
"Could not add attribute '%1' of type %2" ).arg( field.
name() ).arg( field.
type() ) );
622 QString sql = QString(
"SELECT \"fid\" FROM 'log_added_features' WHERE \"layer_id\" = %1" ).arg( layerId );
627 QVector<QVariant> defaultValues( remoteFlds.
count() );
628 for (
int i = 0; i < remoteFlds.
count(); ++i )
636 for (
int i = 0; i < newFeatureIds.size(); i++ )
650 for ( QgsFeatureList::iterator it = features.begin(); it != features.end(); ++it )
656 QMap<int, int> attrLookup =
attributeLookup( offlineLayer, remoteLayer );
659 for (
int it = 0; it < attrs.count(); ++it )
661 newAttrs[ attrLookup[ it ] ] = attrs[ it ];
666 for (
int k = 0; k < newAttrs.count(); ++k )
668 if ( newAttrs[k].
isNull() && !defaultValues[k].isNull() )
669 newAttrs[k] = defaultValues[k];
682 QString sql = QString(
"SELECT \"fid\" FROM 'log_removed_features' WHERE \"layer_id\" = %1" ).arg( layerId );
688 for ( QgsFeatureIds::const_iterator it = values.begin(); it != values.end(); ++it )
699 QString sql = QString(
"SELECT \"fid\", \"attr\", \"value\" FROM 'log_feature_updates' WHERE \"layer_id\" = %1 AND \"commit_no\" = %2 " ).arg( layerId ).arg( commitNo );
704 QMap<int, int> attrLookup =
attributeLookup( offlineLayer, remoteLayer );
706 for (
int i = 0; i < values.size(); i++ )
710 remoteLayer->
changeAttributeValue( fid, attrLookup[ values.at( i ).attr ], values.at( i ).value );
718 QString sql = QString(
"SELECT \"fid\", \"geom_wkt\" FROM 'log_geometry_updates' WHERE \"layer_id\" = %1 AND \"commit_no\" = %2" ).arg( layerId ).arg( commitNo );
723 for (
int i = 0; i < values.size(); i++ )
750 newRemoteFids[ f.
id()] =
true;
758 QString sql = QString(
"SELECT \"fid\" FROM 'log_added_features' WHERE \"layer_id\" = %1" ).arg( layerId );
761 if ( newRemoteFids.size() != newOfflineFids.size() )
770 for ( QMap<QgsFeatureId, bool>::const_iterator it = newRemoteFids.begin(); it != newRemoteFids.end(); ++it )
772 addFidLookup( db, layerId, newOfflineFids.at( i++ ), it.key() );
782 QDomElement node = doc.createElement(
"symbology" );
783 doc.appendChild( node );
786 if ( error.isEmpty() )
790 if ( !error.isEmpty() )
802 QMap <
int ,
int > attrLookup;
804 for (
int i = 0; i < remoteAttrs.size(); i++ )
806 attrLookup.insert( offlineAttrs.at( i ), remoteAttrs.at( i ) );
814 QMessageBox::warning( NULL,
tr(
"Offline Editing Plugin" ), message );
821 if ( !dbPath.isEmpty() )
823 int rc = sqlite3_open( dbPath.toUtf8().constData(), &db );
824 if ( rc != SQLITE_OK )
826 showWarning(
tr(
"Could not open the spatialite logging database" ) );
836 QString sql = QString(
"SELECT \"id\" FROM 'log_layer_ids' WHERE \"qgis_id\" = '%1'" ).arg( qgisLayerId );
841 sql =
"SELECT \"last_index\" FROM 'log_indices' WHERE \"name\" = 'layer_id'";
845 sql = QString(
"INSERT INTO 'log_layer_ids' VALUES (%1, '%2')" ).arg( newLayerId ).arg( qgisLayerId );
850 sql = QString(
"UPDATE 'log_indices' SET 'last_index' = %1 WHERE \"name\" = 'layer_id'" ).arg( newLayerId + 1 );
853 layerId = newLayerId;
861 QString sql =
"SELECT \"last_index\" FROM 'log_indices' WHERE \"name\" = 'commit_no'";
867 QString sql = QString(
"UPDATE 'log_indices' SET 'last_index' = %1 WHERE \"name\" = 'commit_no'" ).arg(
getCommitNo( db ) + 1 );
873 QString sql = QString(
"INSERT INTO 'log_fids' VALUES ( %1, %2, %3 )" ).arg( layerId ).arg( offlineFid ).arg( remoteFid );
879 QString sql = QString(
"SELECT \"remote_fid\" FROM 'log_fids' WHERE \"layer_id\" = %1 AND \"offline_fid\" = %2" ).arg( layerId ).arg( offlineFid );
885 QString sql = QString(
"SELECT \"offline_fid\" FROM 'log_fids' WHERE \"layer_id\" = %1 AND \"remote_fid\" = %2" ).arg( layerId ).arg( remoteFid );
891 QString sql = QString(
"SELECT COUNT(\"fid\") FROM 'log_added_features' WHERE \"layer_id\" = %1 AND \"fid\" = %2" ).arg( layerId ).arg( fid );
898 int rc = sqlite3_exec( db, sql.toUtf8(), NULL, NULL, &errmsg );
899 if ( rc != SQLITE_OK )
908 sqlite3_stmt* stmt = NULL;
909 if ( sqlite3_prepare_v2( db, sql.toUtf8().constData(), -1, &stmt, NULL ) != SQLITE_OK )
915 int value = defaultValue;
916 int ret = sqlite3_step( stmt );
917 if ( ret == SQLITE_ROW )
919 value = sqlite3_column_int( stmt, 0 );
921 sqlite3_finalize( stmt );
930 sqlite3_stmt* stmt = NULL;
931 if ( sqlite3_prepare_v2( db, sql.toUtf8().constData(), -1, &stmt, NULL ) != SQLITE_OK )
937 int ret = sqlite3_step( stmt );
938 while ( ret == SQLITE_ROW )
940 values << sqlite3_column_int( stmt, 0 );
942 ret = sqlite3_step( stmt );
944 sqlite3_finalize( stmt );
951 QList<QgsField> values;
953 sqlite3_stmt* stmt = NULL;
954 if ( sqlite3_prepare_v2( db, sql.toUtf8().constData(), -1, &stmt, NULL ) != SQLITE_OK )
960 int ret = sqlite3_step( stmt );
961 while ( ret == SQLITE_ROW )
963 QgsField field( QString((
const char* )sqlite3_column_text( stmt, 0 ) ),
964 ( QVariant::Type )sqlite3_column_int( stmt, 1 ),
966 sqlite3_column_int( stmt, 2 ),
967 sqlite3_column_int( stmt, 3 ),
968 QString((
const char* )sqlite3_column_text( stmt, 4 ) ) );
971 ret = sqlite3_step( stmt );
973 sqlite3_finalize( stmt );
982 sqlite3_stmt* stmt = NULL;
983 if ( sqlite3_prepare_v2( db, sql.toUtf8().constData(), -1, &stmt, NULL ) != SQLITE_OK )
989 int ret = sqlite3_step( stmt );
990 while ( ret == SQLITE_ROW )
992 values << sqlite3_column_int( stmt, 0 );
994 ret = sqlite3_step( stmt );
996 sqlite3_finalize( stmt );
1005 sqlite3_stmt* stmt = NULL;
1006 if ( sqlite3_prepare_v2( db, sql.toUtf8().constData(), -1, &stmt, NULL ) != SQLITE_OK )
1012 int ret = sqlite3_step( stmt );
1013 while ( ret == SQLITE_ROW )
1016 change.
fid = sqlite3_column_int( stmt, 0 );
1017 change.
attr = sqlite3_column_int( stmt, 1 );
1018 change.
value = QString((
const char* )sqlite3_column_text( stmt, 2 ) );
1021 ret = sqlite3_step( stmt );
1023 sqlite3_finalize( stmt );
1032 sqlite3_stmt* stmt = NULL;
1033 if ( sqlite3_prepare_v2( db, sql.toUtf8().constData(), -1, &stmt, NULL ) != SQLITE_OK )
1039 int ret = sqlite3_step( stmt );
1040 while ( ret == SQLITE_ROW )
1043 change.
fid = sqlite3_column_int( stmt, 0 );
1044 change.
geom_wkt = QString((
const char* )sqlite3_column_text( stmt, 1 ) );
1047 ret = sqlite3_step( stmt );
1049 sqlite3_finalize( stmt );
1066 for ( QList<QgsField>::const_iterator it = addedAttributes.begin(); it != addedAttributes.end(); ++it )
1069 QString sql = QString(
"INSERT INTO 'log_added_attrs' VALUES ( %1, %2, '%3', %4, %5, %6, '%7' )" )
1072 .arg( field.
name() )
1073 .arg( field.
type() )
1081 sqlite3_close( db );
1100 QString sql = QString(
"SELECT ROWID FROM '%1' ORDER BY ROWID DESC LIMIT %2" ).arg( uri.
table() ).arg( addedFeatures.size() );
1102 for (
int i = newFeatureIds.size() - 1; i >= 0; i-- )
1104 QString sql = QString(
"INSERT INTO 'log_added_features' VALUES ( %1, %2 )" )
1106 .arg( newFeatureIds.at( i ) );
1110 sqlite3_close( db );
1124 for ( QgsFeatureIds::const_iterator it = deletedFeatureIds.begin(); it != deletedFeatureIds.end(); ++it )
1129 QString sql = QString(
"DELETE FROM 'log_added_features' WHERE \"layer_id\" = %1 AND \"fid\" = %2" ).arg( layerId ).arg( *it );
1134 QString sql = QString(
"INSERT INTO 'log_removed_features' VALUES ( %1, %2)" )
1141 sqlite3_close( db );
1156 for ( QgsChangedAttributesMap::const_iterator cit = changedAttrsMap.begin(); cit != changedAttrsMap.end(); ++cit )
1165 for ( QgsAttributeMap::const_iterator it = attrMap.begin(); it != attrMap.end(); ++it )
1167 QString sql = QString(
"INSERT INTO 'log_feature_updates' VALUES ( %1, %2, %3, %4, '%5' )" )
1172 .arg( it.value().toString() );
1178 sqlite3_close( db );
1193 for ( QgsGeometryMap::const_iterator it = changedGeometries.begin(); it != changedGeometries.end(); ++it )
1202 QString sql = QString(
"INSERT INTO 'log_geometry_updates' VALUES ( %1, %2, %3, '%4' )" )
1213 sqlite3_close( db );
QgsFeatureId id() const
Get the feature id for this feature.
const QString & name() const
Gets the name of the field.
void increaseCommitNo(sqlite3 *db)
Wrapper for iterator of features from vector data provider or vector layer.
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
void layerProgressUpdated(int layer, int numLayers)
emit a signal that the next layer of numLayers has started processing
sqlite3 * openLoggingDb()
Base class for all map layer types.
void stopListenFeatureChanges()
bool createSpatialiteDB(const QString &offlineDbPath)
QMap< int, QVariant > QgsAttributeMap
#define PROJECT_ENTRY_KEY_OFFLINE_DB_PATH
bool convertToOfflineProject(const QString &offlineDataPath, const QString &offlineDbFile, const QStringList &layerIds)
convert current project for offline editing
void setTypeName(const QString &typ)
Set the field type.
bool isAddedFeature(sqlite3 *db, int layerId, QgsFeatureId fid)
void updateFidLookup(QgsVectorLayer *remoteLayer, sqlite3 *db, int layerId)
bool deleteFeature(QgsFeatureId fid)
delete a feature from the layer (but does not commit it)
QSet< QgsFeatureId > QgsFeatureIds
QList< QgsFeature > QgsFeatureList
#define CUSTOM_PROPERTY_IS_OFFLINE_EDITABLE
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
bool commitChanges()
Attempts to commit any changes to disk.
void addFidLookup(sqlite3 *db, int layerId, QgsFeatureId offlineFid, QgsFeatureId remoteFid)
bool startEditing()
Make layer editable.
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
AttributeValueChanges sqlQueryAttributeValueChanges(sqlite3 *db, const QString &sql)
void committedGeometriesChanges(const QString &qgisLayerId, const QgsGeometryMap &changedGeometries)
#define CUSTOM_PROPERTY_REMOTE_SOURCE
int precision() const
Gets the precision of the field.
GeometryChanges sqlQueryGeometryChanges(sqlite3 *db, const QString &sql)
Container of fields for a vector layer.
void setAttributes(const QgsAttributes &attrs)
bool addFeature(QgsFeature &f, bool alsoUpdateExtent=true)
Adds a feature.
field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QList< int > sqlQueryInts(sqlite3 *db, const QString &sql)
void createLoggingTables(sqlite3 *db)
void applyGeometryChanges(QgsVectorLayer *remoteLayer, sqlite3 *db, int layerId, int commitNo)
QGis::WkbType wkbType() const
Returns the WKBType or WKBUnknown in case of error.
bool isOfflineProject()
return true if current project is offline
const QString & name() const
Get the display name of the layer.
QgsFeatureIds sqlQueryFeaturesRemoved(sqlite3 *db, const QString &sql)
bool writeEntry(const QString &scope, const QString &key, bool value)
void progressUpdated(int progress)
emit a signal with the progress of the current mode
QgsVectorLayerEditBuffer * editBuffer()
Buffer with uncommitted editing operations. Only valid after editing has been turned on...
virtual void reload()
Synchronises with changes in the datasource.
QString exportToWkt() const
Exports the geometry to mWkt.
void progressStopped()
emit a signal that processing of all layers has finished
void initializeSpatialMetadata(sqlite3 *sqlite_handle)
void applyFeaturesRemoved(QgsVectorLayer *remoteLayer, sqlite3 *db, int layerId)
const QString & source() const
Returns the source for the layer.
QList< QgsMapLayer * > addMapLayers(QList< QgsMapLayer * > theMapLayers, bool addToLegend=true, bool takeOwnership=true)
Add a list of layers to the map of loaded layers.
QMap< int, int > attributeLookup(QgsVectorLayer *offlineLayer, QgsVectorLayer *remoteLayer)
int getOrCreateLayerId(sqlite3 *db, const QString &qgisLayerId)
int fieldOriginIndex(int fieldIdx) const
Get field's origin index (its meaning is specific to each type of origin)
const QList< NativeType > & nativeTypes() const
Returns the names of the supported types.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
void startListenFeatureChanges()
QList< int > QgsAttributeList
Q_DECL_DEPRECATED bool changeAttributeValue(QgsFeatureId fid, int field, QVariant value, bool emitSignal)
Changes an attribute value (but does not commit it)
const QgsAttributes & attributes() const
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
bool removeEntry(const QString &scope, const QString &key)
remove the given key
int count() const
Return number of items.
bool changeGeometry(QgsFeatureId fid, QgsGeometry *geom)
change feature's geometry
QgsFeatureId offlineFid(sqlite3 *db, int layerId, QgsFeatureId remoteFid)
int sqlExec(sqlite3 *db, const QString &sql)
Encapsulate a field in an attribute table or data source.
void applyFeaturesAdded(QgsVectorLayer *offlineLayer, QgsVectorLayer *remoteLayer, sqlite3 *db, int layerId)
QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
void layerAdded(QgsMapLayer *layer)
QList< QgsField > sqlQueryAttributesAdded(sqlite3 *db, const QString &sql)
#define PROJECT_ENTRY_SCOPE_OFFLINE
const QStringList & commitErrors()
QgsFeatureId remoteFid(sqlite3 *db, int layerId, QgsFeatureId offlineFid)
bool readSymbology(const QDomNode &node, QString &errorMessage)
Read the symbology for the current layer from the Dom node supplied.
Class for storing the component parts of a PostgreSQL/RDBMS datasource URI.
QList< GeometryChange > GeometryChanges
void copyVectorLayer(QgsVectorLayer *layer, sqlite3 *db, const QString &offlineDbPath)
QString providerType() const
Return the provider type for this layer.
QList< AttributeValueChange > AttributeValueChanges
virtual long featureCount() const
Number of features in the layer.
virtual const QgsFields & fields() const =0
Return a map of indexes with field names for this layer.
QString readEntry(const QString &scope, const QString &key, const QString &def=QString::null, bool *ok=0) const
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QgsAttributeList pendingAllAttributesList()
returns list of attributes
virtual QVariant defaultValue(int fieldId)
Returns the default value for field specified by fieldId.
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
void removeMapLayers(QStringList theLayerIds)
Remove a set of layers from the registry.
void title(const QString &title)
Every project has an associated title string.
QVector< QVariant > QgsAttributes
void synchronize()
synchronize to remote layers
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
void committedFeaturesAdded(const QString &qgisLayerId, const QgsFeatureList &addedFeatures)
virtual bool setSubsetString(QString subset)
Set the string (typically sql) used to define a subset of the layer.
int getCommitNo(sqlite3 *db)
static QgsProject * instance()
access to canonical QgsProject instance
int length() const
Gets the length of the field.
void committedAttributesAdded(const QString &qgisLayerId, const QList< QgsField > &addedAttributes)
bool hasLabelsEnabled() const
Label is on.
const QMap< QString, QgsMapLayer * > & mapLayers()
Retrieve the mapLayers collection (mainly intended for use by projection)
const QString & comment() const
Returns the field comment.
void progressModeSet(QgsOfflineEditing::ProgressMode mode, int maximum)
emit a signal that sets the mode for the progress of the current operation
static QgsGeometry * fromWkt(QString wkt)
static method that creates geometry from Wkt
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
void copySymbology(const QgsVectorLayer *sourceLayer, QgsVectorLayer *targetLayer)
int sqlQueryInt(sqlite3 *db, const QString &sql, int defaultValue)
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
QgsVectorDataProvider * dataProvider()
Returns the data provider.
bool nextFeature(QgsFeature &f)
This is the base class for vector data providers.
Geometry is not required. It may still be returned if e.g. required for a filter condition.
void applyAttributesAdded(QgsVectorLayer *remoteLayer, sqlite3 *db, int layerId, int commitNo)
bool writeSymbology(QDomNode &node, QDomDocument &doc, QString &errorMessage) const
Write the symbology for the layer into the docment provided.
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 ...
void applyAttributeValueChanges(QgsVectorLayer *offlineLayer, QgsVectorLayer *remoteLayer, sqlite3 *db, int layerId, int commitNo)
#define CUSTOM_PROPERTY_REMOTE_PROVIDER
void committedFeaturesRemoved(const QString &qgisLayerId, const QgsFeatureIds &deletedFeatureIds)
void progressStarted()
emit a signal that processing has started
bool isNull(const QVariant &v)
void showWarning(const QString &message)
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
void committedAttributeValuesChanges(const QString &qgisLayerId, const QgsChangedAttributesMap &changedAttrsMap)