Skip to content

Commit eb39278

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 f80021e commit eb39278

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
@@ -77,7 +77,7 @@ QgsOfflineEditing::~QgsOfflineEditing()
7777
* - remove remote layers
7878
* - mark as offline project
7979
*/
80-
bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath, const QString& offlineDbFile, const QStringList& layerIds )
80+
bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath, const QString& offlineDbFile, const QStringList& layerIds, bool onlySelected )
8181
{
8282
if ( layerIds.isEmpty() )
8383
{
@@ -102,9 +102,9 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath,
102102
QMap<QString, QgsVectorJoinList > joinInfoBuffer;
103103
QMap<QString, QgsVectorLayer*> layerIdMapping;
104104

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

124124
if ( vl )
125-
( *it ).prefix = vl->name() + '_';
125+
joinIt->prefix = vl->name() + '_';
126126
}
127-
++it;
127+
++joinIt;
128128
}
129129
joinInfoBuffer.insert( vl->id(), joins );
130130
}
@@ -139,7 +139,7 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath,
139139
if ( vl )
140140
{
141141
QString origLayerId = vl->id();
142-
QgsVectorLayer* newLayer = copyVectorLayer( vl, db, dbPath );
142+
QgsVectorLayer* newLayer = copyVectorLayer( vl, db, dbPath, onlySelected );
143143

144144
if ( newLayer )
145145
{
@@ -195,7 +195,7 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath,
195195
return false;
196196
}
197197

198-
bool QgsOfflineEditing::isOfflineProject()
198+
bool QgsOfflineEditing::isOfflineProject() const
199199
{
200200
return !QgsProject::instance()->readEntry( PROJECT_ENTRY_SCOPE_OFFLINE, PROJECT_ENTRY_KEY_OFFLINE_DB_PATH ).isEmpty();
201201
}
@@ -226,7 +226,7 @@ void QgsOfflineEditing::synchronize()
226226
QgsDebugMsgLevel( QString( "Found %1 offline layers" ).arg( offlineLayers.count() ), 4 );
227227
for ( int l = 0; l < offlineLayers.count(); l++ )
228228
{
229-
QgsMapLayer* layer = offlineLayers[l];
229+
QgsMapLayer* layer = offlineLayers.at( l );
230230

231231
emit layerProgressUpdated( l + 1, offlineLayers.count() );
232232

@@ -252,8 +252,7 @@ void QgsOfflineEditing::synchronize()
252252
QgsVectorLayer* offlineLayer = qobject_cast<QgsVectorLayer*>( layer );
253253

254254
// register this layer with the central layers registry
255-
QgsMapLayerRegistry::instance()->addMapLayers(
256-
QList<QgsMapLayer *>() << remoteLayer, true );
255+
QgsMapLayerRegistry::instance()->addMapLayers( QList<QgsMapLayer *>() << remoteLayer, true );
257256

258257
// copy style
259258
copySymbology( offlineLayer, remoteLayer );
@@ -315,8 +314,7 @@ void QgsOfflineEditing::synchronize()
315314
// again with the same path
316315
offlineLayer->dataProvider()->invalidateConnections( QgsDataSourceURI( offlineLayer->source() ).database() );
317316
// remove offline layer
318-
QgsMapLayerRegistry::instance()->removeMapLayers(
319-
( QStringList() << qgisLayerId ) );
317+
QgsMapLayerRegistry::instance()->removeMapLayers( QStringList() << qgisLayerId );
320318

321319

322320
// disable offline project
@@ -484,7 +482,7 @@ void QgsOfflineEditing::createLoggingTables( sqlite3* db )
484482
*/
485483
}
486484

487-
QgsVectorLayer* QgsOfflineEditing::copyVectorLayer( QgsVectorLayer* layer, sqlite3* db, const QString& offlineDbPath )
485+
QgsVectorLayer* QgsOfflineEditing::copyVectorLayer( QgsVectorLayer* layer, sqlite3* db, const QString& offlineDbPath , bool onlySelected )
488486
{
489487
if ( !layer )
490488
return nullptr;
@@ -637,12 +635,18 @@ QgsVectorLayer* QgsOfflineEditing::copyVectorLayer( QgsVectorLayer* layer, sqlit
637635

638636
QgsFeatureIterator fit = layer->dataProvider()->getFeatures();
639637

638+
QgsFeatureIds selectedFids = layer->selectedFeaturesIds();
639+
640640
emit progressModeSet( QgsOfflineEditing::CopyFeatures, layer->dataProvider()->featureCount() );
641641
int featureCount = 1;
642642

643643
QList<QgsFeatureId> remoteFeatureIds;
644644
while ( fit.nextFeature( f ) )
645645
{
646+
// Check if we only want selected feature, if the selection is not empty and the current feature is not selected: dismiss it
647+
if ( onlySelected && !selectedFids.isEmpty() && !selectedFids.contains( f.id() ) )
648+
continue;
649+
646650
remoteFeatureIds << f.id();
647651

648652
// 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)