Skip to content

Commit 59a3bc2

Browse files
committed
[feature] Add flag to only copy selected features
This extends the offline editing possibilities to only work on subset of large layers Sponsored by DB Fahrwegdienste GmbH
1 parent d393734 commit 59a3bc2

7 files changed

+48
-30
lines changed

python/core/qgsofflineediting.sip

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ class QgsOfflineEditing : QObject
2828
* @param offlineDbFile offline db file name
2929
* @param layerIds list of layer names to convert
3030
*/
31-
bool convertToOfflineProject( const QString& offlineDataPath, const QString& offlineDbFile, const QStringList& layerIds );
31+
bool convertToOfflineProject( const QString& offlineDataPath, const QString& offlineDbFile, const QStringList& layerIds, bool onlySelected = false );
3232

3333
/** Return true if current project is offline */
34-
bool isOfflineProject();
34+
bool isOfflineProject() const;
3535

3636
/** Synchronize to remote layers */
3737
void synchronize();

src/core/qgsofflineediting.cpp

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ QgsOfflineEditing::~QgsOfflineEditing()
7979
* - remove remote layers
8080
* - mark as offline project
8181
*/
82-
bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath, const QString& offlineDbFile, const QStringList& layerIds )
82+
bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath, const QString& offlineDbFile, const QStringList& layerIds, bool onlySelected )
8383
{
8484
if ( layerIds.isEmpty() )
8585
{
@@ -104,9 +104,9 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath,
104104
QMap<QString, QgsVectorJoinList > joinInfoBuffer;
105105
QMap<QString, QgsVectorLayer*> layerIdMapping;
106106

107-
for ( int i = 0; i < layerIds.count(); i++ )
107+
Q_FOREACH ( const QString& layerId, layerIds )
108108
{
109-
QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( layerIds.at( i ) );
109+
QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( layerId );
110110
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( layer );
111111
if ( !vl )
112112
continue;
@@ -116,17 +116,17 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath,
116116
// Join fields are prefixed with the layer name and we do not want the
117117
// field name to change so we stabilize the field name by defining a
118118
// custom prefix with the layername without _offline suffix.
119-
QgsVectorJoinList::iterator it = joins.begin();
120-
while ( it != joins.end() )
119+
QgsVectorJoinList::iterator joinIt = joins.begin();
120+
while ( joinIt != joins.end() )
121121
{
122-
if (( *it ).prefix.isNull() )
122+
if ( joinIt->prefix.isNull() )
123123
{
124-
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer(( *it ).joinLayerId ) );
124+
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinIt->joinLayerId ) );
125125

126126
if ( vl )
127-
( *it ).prefix = vl->name() + '_';
127+
joinIt->prefix = vl->name() + '_';
128128
}
129-
++it;
129+
++joinIt;
130130
}
131131
joinInfoBuffer.insert( vl->id(), joins );
132132
}
@@ -141,7 +141,7 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath,
141141
if ( vl )
142142
{
143143
QString origLayerId = vl->id();
144-
QgsVectorLayer* newLayer = copyVectorLayer( vl, db, dbPath );
144+
QgsVectorLayer* newLayer = copyVectorLayer( vl, db, dbPath, onlySelected );
145145

146146
if ( newLayer )
147147
{
@@ -197,7 +197,7 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath,
197197
return false;
198198
}
199199

200-
bool QgsOfflineEditing::isOfflineProject()
200+
bool QgsOfflineEditing::isOfflineProject() const
201201
{
202202
return !QgsProject::instance()->readEntry( PROJECT_ENTRY_SCOPE_OFFLINE, PROJECT_ENTRY_KEY_OFFLINE_DB_PATH ).isEmpty();
203203
}
@@ -228,7 +228,7 @@ void QgsOfflineEditing::synchronize()
228228
QgsDebugMsgLevel( QString( "Found %1 offline layers" ).arg( offlineLayers.count() ), 4 );
229229
for ( int l = 0; l < offlineLayers.count(); l++ )
230230
{
231-
QgsMapLayer* layer = offlineLayers[l];
231+
QgsMapLayer* layer = offlineLayers.at( l );
232232

233233
emit layerProgressUpdated( l + 1, offlineLayers.count() );
234234

@@ -254,8 +254,7 @@ void QgsOfflineEditing::synchronize()
254254
QgsVectorLayer* offlineLayer = qobject_cast<QgsVectorLayer*>( layer );
255255

256256
// register this layer with the central layers registry
257-
QgsMapLayerRegistry::instance()->addMapLayers(
258-
QList<QgsMapLayer *>() << remoteLayer, true );
257+
QgsMapLayerRegistry::instance()->addMapLayers( QList<QgsMapLayer *>() << remoteLayer, true );
259258

260259
// copy style
261260
copySymbology( offlineLayer, remoteLayer );
@@ -317,8 +316,7 @@ void QgsOfflineEditing::synchronize()
317316
// again with the same path
318317
offlineLayer->dataProvider()->invalidateConnections( QgsDataSourceUri( offlineLayer->source() ).database() );
319318
// remove offline layer
320-
QgsMapLayerRegistry::instance()->removeMapLayers(
321-
( QStringList() << qgisLayerId ) );
319+
QgsMapLayerRegistry::instance()->removeMapLayers( QStringList() << qgisLayerId );
322320

323321

324322
// disable offline project
@@ -486,7 +484,7 @@ void QgsOfflineEditing::createLoggingTables( sqlite3* db )
486484
*/
487485
}
488486

489-
QgsVectorLayer* QgsOfflineEditing::copyVectorLayer( QgsVectorLayer* layer, sqlite3* db, const QString& offlineDbPath )
487+
QgsVectorLayer* QgsOfflineEditing::copyVectorLayer( QgsVectorLayer* layer, sqlite3* db, const QString& offlineDbPath , bool onlySelected )
490488
{
491489
if ( !layer )
492490
return nullptr;
@@ -626,12 +624,18 @@ QgsVectorLayer* QgsOfflineEditing::copyVectorLayer( QgsVectorLayer* layer, sqlit
626624

627625
QgsFeatureIterator fit = layer->dataProvider()->getFeatures();
628626

627+
QgsFeatureIds selectedFids = layer->selectedFeaturesIds();
628+
629629
emit progressModeSet( QgsOfflineEditing::CopyFeatures, layer->dataProvider()->featureCount() );
630630
int featureCount = 1;
631631

632632
QList<QgsFeatureId> remoteFeatureIds;
633633
while ( fit.nextFeature( f ) )
634634
{
635+
// Check if we only want selected feature, if the selection is not empty and the current feature is not selected: dismiss it
636+
if ( onlySelected && !selectedFids.isEmpty() && !selectedFids.contains( f.id() ) )
637+
continue;
638+
635639
remoteFeatureIds << f.id();
636640

637641
// NOTE: Spatialite provider ignores position of geometry column

src/core/qgsofflineediting.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,15 @@ class CORE_EXPORT QgsOfflineEditing : public QObject
5151
~QgsOfflineEditing();
5252

5353
/** Convert current project for offline editing
54-
* @param offlineDataPath path to offline db file
55-
* @param offlineDbFile offline db file name
56-
* @param layerIds list of layer names to convert
54+
* @param offlineDataPath Path to offline db file
55+
* @param offlineDbFile Offline db file name
56+
* @param layerIds List of layer names to convert
57+
* @param onlySelected Only copy selected features from layers where a selection is present
5758
*/
58-
bool convertToOfflineProject( const QString& offlineDataPath, const QString& offlineDbFile, const QStringList& layerIds );
59+
bool convertToOfflineProject( const QString& offlineDataPath, const QString& offlineDbFile, const QStringList& layerIds, bool onlySelected = false );
5960

6061
/** Return true if current project is offline */
61-
bool isOfflineProject();
62+
bool isOfflineProject() const;
6263

6364
/** Synchronize to remote layers */
6465
void synchronize();
@@ -98,7 +99,7 @@ class CORE_EXPORT QgsOfflineEditing : public QObject
9899
void initializeSpatialMetadata( sqlite3 *sqlite_handle );
99100
bool createSpatialiteDB( const QString& offlineDbPath );
100101
void createLoggingTables( sqlite3* db );
101-
QgsVectorLayer* copyVectorLayer( QgsVectorLayer* layer, sqlite3* db, const QString& offlineDbPath );
102+
QgsVectorLayer* copyVectorLayer( QgsVectorLayer* layer, sqlite3* db, const QString& offlineDbPath, bool onlySelected );
102103

103104
void applyAttributesAdded( QgsVectorLayer* remoteLayer, sqlite3* db, int layerId, int commitNo );
104105
void applyFeaturesAdded( QgsVectorLayer* offlineLayer, QgsVectorLayer* remoteLayer, sqlite3* db, int layerId );

src/plugins/offline_editing/offline_editing_plugin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ void QgsOfflineEditingPlugin::convertProject()
109109
}
110110

111111
mProgressDialog->setTitle( tr( "Converting to offline project" ) );
112-
if ( mOfflineEditing->convertToOfflineProject( myPluginGui->offlineDataPath(), myPluginGui->offlineDbFile(), selectedLayerIds ) )
112+
if ( mOfflineEditing->convertToOfflineProject( myPluginGui->offlineDataPath(), myPluginGui->offlineDbFile(), selectedLayerIds, myPluginGui->onlySelected() ) )
113113
{
114114
updateActions();
115115
// Redraw, to make the offline layer visible

src/plugins/offline_editing/offline_editing_plugin_gui.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,16 @@ QString QgsOfflineEditingPluginGui::offlineDbFile()
102102
return mOfflineDbFile;
103103
}
104104

105-
QStringList& QgsOfflineEditingPluginGui::selectedLayerIds()
105+
QStringList QgsOfflineEditingPluginGui::selectedLayerIds()
106106
{
107107
return mSelectedLayerIds;
108108
}
109109

110+
bool QgsOfflineEditingPluginGui::onlySelected() const
111+
{
112+
return mOnlySelectedCheckBox->checkState() == Qt::Checked;
113+
}
114+
110115
void QgsOfflineEditingPluginGui::on_mBrowseButton_clicked()
111116
{
112117
QString fileName = QFileDialog::getSaveFileName( this,

src/plugins/offline_editing/offline_editing_plugin_gui.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ class QgsOfflineEditingPluginGui : public QDialog, private Ui::QgsOfflineEditing
4646

4747
QString offlineDataPath();
4848
QString offlineDbFile();
49-
QStringList& selectedLayerIds();
49+
QStringList selectedLayerIds();
50+
bool onlySelected() const;
5051

5152
public slots:
5253
/** Change the selection of layers in the list */

src/plugins/offline_editing/offline_editing_plugin_guibase.ui

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>435</width>
10-
<height>270</height>
9+
<width>590</width>
10+
<height>570</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
@@ -92,6 +92,13 @@
9292
</item>
9393
</layout>
9494
</item>
95+
<item>
96+
<widget class="QCheckBox" name="mOnlySelectedCheckBox">
97+
<property name="text">
98+
<string>Only synchronize selected features if a selection is present</string>
99+
</property>
100+
</widget>
101+
</item>
95102
<item>
96103
<layout class="QHBoxLayout" name="horizontalLayout_2">
97104
<item>

0 commit comments

Comments
 (0)