Skip to content

Commit e1adc63

Browse files
committedJan 15, 2016
Merge pull request #2678 from m-kuhn/transaction-group
[FEATURE] Autotransaction mode and transaction groups
2 parents 01434e8 + 8ee25b7 commit e1adc63

16 files changed

+685
-106
lines changed
 

‎python/core/core.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
%Include qgis.sip
2020

2121
%Include qgstransaction.sip
22+
%Include qgstransactiongroup.sip
2223
%Include qgsapplication.sip
2324
%Include qgsattributeaction.sip
2425
%Include qgsbrowsermodel.sip

‎python/core/qgstransaction.sip

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ class QgsTransaction : QObject /Abstract/
5959
/** Executes sql */
6060
virtual bool executeSql( const QString& sql, QString& error /Out/ ) = 0;
6161

62+
/**
63+
* Checks if a the provider of a give layer supports transactions.
64+
*/
65+
static bool supportsTransaction( const QgsVectorLayer* layer );
66+
6267
signals:
6368
/**
6469
* Emitted after a rollback

‎python/core/qgstransactiongroup.sip

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/***************************************************************************
2+
qgstransactiongroup.h - QgsTransactionGroup
3+
4+
---------------------
5+
begin : 15.1.2016
6+
copyright : (C) 2016 by Matthias Kuhn
7+
email : mmatthias@opengis.ch
8+
***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
17+
class QgsTransactionGroup : QObject
18+
{
19+
%TypeHeaderCode
20+
#include "qgstransactiongroup.h"
21+
%End
22+
public:
23+
explicit QgsTransactionGroup( QObject *parent = 0 );
24+
25+
~QgsTransactionGroup();
26+
27+
/**
28+
* Add a layer to this transaction group.
29+
*
30+
* Will return true if it is compatible and has been added.
31+
*/
32+
bool addLayer( QgsVectorLayer* layer );
33+
34+
/**
35+
* Return the connection string used by this transaction group.
36+
* Layers need be compatible when added.
37+
*/
38+
QString connString() const;
39+
40+
/**
41+
* Return the provider key used by this transaction group.
42+
* Layers need be compatible when added.
43+
*/
44+
QString providerKey() const;
45+
46+
/**
47+
* Returns true if there are no layers in this transaction group.
48+
*/
49+
bool isEmpty() const;
50+
51+
signals:
52+
/**
53+
* Will be emitted whenever there is a commit error
54+
*/
55+
void commitError( const QString& msg );
56+
};

‎python/core/qgsvectorlayer.sip

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,14 +1015,6 @@ class QgsVectorLayer : QgsMapLayer
10151015
*/
10161016
bool setReadOnly( bool readonly = true );
10171017

1018-
/**
1019-
* Make layer editable.
1020-
* This starts an edit session on this layer. Changes made in this edit session will not
1021-
* be made persistent until {@link commitChanges()} is called and can be reverted by calling
1022-
* {@link rollBack()}.
1023-
*/
1024-
bool startEditing();
1025-
10261018
/** Change feature's geometry */
10271019
bool changeGeometry( QgsFeatureId fid, QgsGeometry* geom );
10281020

@@ -1493,6 +1485,15 @@ class QgsVectorLayer : QgsMapLayer
14931485
/** Check if there is a join with a layer that will be removed */
14941486
void checkJoinLayerRemove( const QString& theLayerId );
14951487

1488+
/**
1489+
* Make layer editable.
1490+
* This starts an edit session on this layer. Changes made in this edit session will not
1491+
* be made persistent until {@link commitChanges()} is called and can be reverted by calling
1492+
* {@link rollBack()}.
1493+
*/
1494+
bool startEditing();
1495+
1496+
14961497
protected slots:
14971498
void invalidateSymbolCountedFlag();
14981499

@@ -1516,6 +1517,9 @@ class QgsVectorLayer : QgsMapLayer
15161517
/** Is emitted, when layer is checked for modifications. Use for last-minute additions */
15171518
void beforeModifiedCheck() const;
15181519

1520+
/** Is emitted, before editing on this layer is started */
1521+
void beforeEditingStarted();
1522+
15191523
/** Is emitted, when editing on this layer has started*/
15201524
void editingStarted();
15211525

@@ -1663,10 +1667,6 @@ class QgsVectorLayer : QgsMapLayer
16631667
*/
16641668
void writeCustomSymbology( QDomElement& element, QDomDocument& doc, QString& errorMessage ) const;
16651669

1666-
private slots:
1667-
void onRelationsLoaded();
1668-
void onJoinedFieldsChanged();
1669-
void onFeatureDeleted( QgsFeatureId fid );
16701670

16711671
protected:
16721672
/** Set the extent */

‎src/app/qgisapp.cpp

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@
233233
#include "qgslegendfilterbutton.h"
234234
#include "qgsvirtuallayerdefinition.h"
235235
#include "qgsvirtuallayerdefinitionutils.h"
236+
#include "qgstransaction.h"
237+
#include "qgstransactiongroup.h"
236238

237239
#include "qgssublayersdialog.h"
238240
#include "ogr/qgsopenvectorlayerdialog.h"
@@ -7512,6 +7514,22 @@ void QgisApp::removingLayers( const QStringList& theLayers )
75127514

75137515
toggleEditing( vlayer, false );
75147516
}
7517+
7518+
if ( autoTransaction() )
7519+
{
7520+
for ( QMap< QPair< QString, QString>, QgsTransactionGroup*>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
7521+
{
7522+
if ( tg.value()->isEmpty() )
7523+
{
7524+
delete tg.value();
7525+
tg = mTransactionGroups.erase( tg );
7526+
}
7527+
else
7528+
{
7529+
++tg;
7530+
}
7531+
}
7532+
}
75157533
}
75167534

75177535
void QgisApp::removeAllLayers()
@@ -9334,9 +9352,8 @@ void QgisApp::extentChanged()
93349352

93359353
void QgisApp::layersWereAdded( const QList<QgsMapLayer *>& theLayers )
93369354
{
9337-
for ( int i = 0; i < theLayers.size(); ++i )
9355+
Q_FOREACH ( QgsMapLayer* layer, theLayers )
93389356
{
9339-
QgsMapLayer * layer = theLayers.at( i );
93409357
QgsDataProvider *provider = nullptr;
93419358

93429359
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
@@ -9352,6 +9369,27 @@ void QgisApp::layersWereAdded( const QList<QgsMapLayer *>& theLayers )
93529369
connect( vlayer, SIGNAL( editingStarted() ), this, SLOT( layerEditStateChanged() ) );
93539370
connect( vlayer, SIGNAL( editingStopped() ), this, SLOT( layerEditStateChanged() ) );
93549371
}
9372+
9373+
if ( autoTransaction() )
9374+
{
9375+
if ( QgsTransaction::supportsTransaction( vlayer ) )
9376+
{
9377+
QString connString = QgsDataSourceURI( vlayer->source() ).connectionInfo();
9378+
QString key = vlayer->providerType();
9379+
9380+
QgsTransactionGroup* tg = mTransactionGroups.value( qMakePair( key, connString ) );
9381+
9382+
if ( !tg )
9383+
{
9384+
tg = new QgsTransactionGroup();
9385+
mTransactionGroups.insert( qMakePair( key, connString ), tg );
9386+
9387+
connect( tg, SIGNAL( commitError ), this, SLOT( displayMapToolMessage( QString, QgsMessageBar::MessageLevel ) ) );
9388+
}
9389+
tg->addLayer( vlayer );
9390+
}
9391+
}
9392+
93559393
provider = vProvider;
93569394
}
93579395

@@ -9995,6 +10033,23 @@ void QgisApp::refreshActionFeatureAction()
999510033
mActionFeatureAction->setEnabled( layerHasActions );
999610034
}
999710035

10036+
bool QgisApp::autoTransaction() const
10037+
{
10038+
QSettings settings;
10039+
return settings.value( "/qgis/autoTransaction", false ).toBool();
10040+
}
10041+
10042+
void QgisApp::setAutoTransaction( bool state )
10043+
{
10044+
QSettings settings;
10045+
10046+
if ( settings.value( "/qgis/autoTransaction", false ).toBool() != state )
10047+
{
10048+
10049+
settings.setValue( "/qgis/autoTransaction", state );
10050+
}
10051+
}
10052+
999810053
/////////////////////////////////////////////////////////////////
999910054
//
1000010055
//

‎src/app/qgisapp.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class QgsProviderRegistry;
6464
class QgsPythonUtils;
6565
class QgsRectangle;
6666
class QgsSnappingUtils;
67+
class QgsTransactionGroup;
6768
class QgsUndoWidget;
6869
class QgsUserInputDockWidget;
6970
class QgsVectorLayer;
@@ -671,6 +672,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
671672

672673
QMenu *panelMenu() { return mPanelMenu; }
673674

675+
bool autoTransaction() const;
676+
void setAutoTransaction( bool state );
677+
674678
protected:
675679

676680
//! Handle state changes (WindowTitleChange)
@@ -1668,6 +1672,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
16681672

16691673
QgsComposerManager *mComposerManager;
16701674

1675+
//! map of transaction group: QPair( providerKey, connString ) -> transactionGroup
1676+
QMap< QPair< QString, QString>, QgsTransactionGroup*> mTransactionGroups;
1677+
16711678
//! Persistent tile scale slider
16721679
QgsTileScaleWidget *mpTileScaleWidget;
16731680

‎src/app/qgsoptions.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl ) :
591591
cbxAddOracleDC->setChecked( mSettings->value( "/qgis/addOracleDC", false ).toBool() );
592592
cbxCompileExpressions->setChecked( mSettings->value( "/qgis/compileExpressions", true ).toBool() );
593593
cbxCreateRasterLegendIcons->setChecked( mSettings->value( "/qgis/createRasterLegendIcons", false ).toBool() );
594+
cbxAutoTransaction->setChecked( QgisApp::instance()->autoTransaction() );
594595
cbxCopyWKTGeomFromTable->setChecked( mSettings->value( "/qgis/copyGeometryAsWKT", true ).toBool() );
595596
leNullValue->setText( mSettings->value( "qgis/nullValue", "NULL" ).toString() );
596597
cbxIgnoreShapeEncoding->setChecked( mSettings->value( "/qgis/ignoreShapeEncoding", true ).toBool() );
@@ -1141,6 +1142,7 @@ void QgsOptions::saveOptions()
11411142
mSettings->setValue( "/qgis/defaultLegendGraphicResolution", mLegendGraphicResolutionSpinBox->value() );
11421143
bool createRasterLegendIcons = mSettings->value( "/qgis/createRasterLegendIcons", false ).toBool();
11431144
mSettings->setValue( "/qgis/createRasterLegendIcons", cbxCreateRasterLegendIcons->isChecked() );
1145+
QgisApp::instance()->setAutoTransaction( cbxAutoTransaction->isChecked() );
11441146
mSettings->setValue( "/qgis/copyGeometryAsWKT", cbxCopyWKTGeomFromTable->isChecked() );
11451147
mSettings->setValue( "/qgis/new_layers_visible", chkAddedVisibility->isChecked() );
11461148
mSettings->setValue( "/qgis/enable_anti_aliasing", chkAntiAliasing->isChecked() );

‎src/core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ SET(QGIS_CORE_SRCS
190190
qgstolerance.cpp
191191
qgstracer.cpp
192192
qgstransaction.cpp
193+
qgstransactiongroup.cpp
193194
qgsvectordataprovider.cpp
194195
qgsvectorfilewriter.cpp
195196
qgsvectorlayer.cpp
@@ -459,6 +460,7 @@ SET(QGIS_CORE_MOC_HDRS
459460
qgssnappingutils.h
460461
qgstracer.h
461462
qgstransaction.h
463+
qgstransactiongroup.h
462464
qgsvectordataprovider.h
463465
qgsvectorlayercache.h
464466
qgsvectorlayereditbuffer.h

‎src/core/qgstransaction.cpp

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,12 @@ QgsTransaction::~QgsTransaction()
8383

8484
bool QgsTransaction::addLayer( const QString& layerId )
8585
{
86-
if ( mTransactionActive )
87-
return false;
88-
8986
QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerId ) );
9087
return addLayer( layer );
9188
}
9289

9390
bool QgsTransaction::addLayer( QgsVectorLayer* layer )
9491
{
95-
if ( mTransactionActive )
96-
return false;
97-
9892
if ( !layer )
9993
return false;
10094

@@ -119,6 +113,10 @@ bool QgsTransaction::addLayer( QgsVectorLayer* layer )
119113
connect( this, SIGNAL( afterRollback() ), layer->dataProvider(), SIGNAL( dataChanged() ) );
120114
connect( QgsMapLayerRegistry::instance(), SIGNAL( layersWillBeRemoved( QStringList ) ), this, SLOT( onLayersDeleted( QStringList ) ) );
121115
mLayers.insert( layer );
116+
117+
if ( mTransactionActive )
118+
layer->dataProvider()->setTransaction( this );
119+
122120
return true;
123121
}
124122

@@ -141,14 +139,6 @@ bool QgsTransaction::commit( QString& errorMsg )
141139
if ( !mTransactionActive )
142140
return false;
143141

144-
Q_FOREACH ( QgsVectorLayer* l, mLayers )
145-
{
146-
if ( !l || l->isEditable() )
147-
{
148-
return false;
149-
}
150-
}
151-
152142
if ( !commitTransaction( errorMsg ) )
153143
return false;
154144

@@ -162,14 +152,6 @@ bool QgsTransaction::rollback( QString& errorMsg )
162152
if ( !mTransactionActive )
163153
return false;
164154

165-
Q_FOREACH ( QgsVectorLayer* l, mLayers )
166-
{
167-
if ( l->isEditable() )
168-
{
169-
return false;
170-
}
171-
}
172-
173155
if ( !rollbackTransaction( errorMsg ) )
174156
return false;
175157

@@ -181,6 +163,15 @@ bool QgsTransaction::rollback( QString& errorMsg )
181163
return true;
182164
}
183165

166+
bool QgsTransaction::supportsTransaction( const QgsVectorLayer* layer )
167+
{
168+
QLibrary* lib = QgsProviderRegistry::instance()->providerLibrary( layer->providerType() );
169+
if ( !lib )
170+
return false;
171+
172+
return lib->resolve( "createTransaction" );
173+
}
174+
184175
void QgsTransaction::onLayersDeleted( const QStringList& layerids )
185176
{
186177
Q_FOREACH ( const QString& layerid, layerids )

‎src/core/qgstransaction.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ class CORE_EXPORT QgsTransaction : public QObject
6060

6161
virtual ~QgsTransaction();
6262

63-
/** Add layer to the transaction. The layer must not be in edit mode. The transaction must not be active. */
63+
/** Add layer to the transaction. The layer must not be in edit mode.*/
6464
bool addLayer( const QString& layerId );
6565

66-
/** Add layer to the transaction. The layer must not be in edit mode. The transaction must not be active. */
66+
/** Add layer to the transaction. The layer must not be in edit mode.*/
6767
bool addLayer( QgsVectorLayer* layer );
6868

6969
/** Begin transaction
@@ -76,15 +76,20 @@ class CORE_EXPORT QgsTransaction : public QObject
7676
* Some providers might not honour the statement timeout. */
7777
bool begin( QString& errorMsg, int statementTimeout = 20 );
7878

79-
/** Commit transaction. All layers need to be in read-only mode. */
79+
/** Commit transaction. */
8080
bool commit( QString& errorMsg );
8181

82-
/** Roll back transaction. All layers need to be in read-only mode. */
82+
/** Roll back transaction. */
8383
bool rollback( QString& errorMsg );
8484

8585
/** Executes sql */
8686
virtual bool executeSql( const QString& sql, QString& error ) = 0;
8787

88+
/**
89+
* Checks if a the provider of a give layer supports transactions.
90+
*/
91+
static bool supportsTransaction( const QgsVectorLayer* layer );
92+
8893
signals:
8994
/**
9095
* Emitted after a rollback

‎src/core/qgstransactiongroup.cpp

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/***************************************************************************
2+
qgstransactiongroup.cpp - QgsTransactionGroup
3+
4+
---------------------
5+
begin : 15.1.2016
6+
copyright : (C) 2016 by mku
7+
email : [your-email-here]
8+
***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
#include "qgstransactiongroup.h"
17+
18+
#include "qgstransaction.h"
19+
#include "qgsvectorlayer.h"
20+
#include "qgsdatasourceuri.h"
21+
#include "qgsvectordataprovider.h"
22+
23+
#include <QTimer>
24+
25+
QgsTransactionGroup::QgsTransactionGroup( QObject *parent )
26+
: QObject( parent )
27+
, mEditingStarting( false )
28+
, mEditingStopping( false )
29+
, mTransaction( nullptr )
30+
{
31+
32+
}
33+
34+
QgsTransactionGroup::~QgsTransactionGroup()
35+
{
36+
delete mTransaction;
37+
}
38+
39+
bool QgsTransactionGroup::addLayer( QgsVectorLayer* layer )
40+
{
41+
if ( !QgsTransaction::supportsTransaction( layer ) )
42+
return false;
43+
44+
QString connString = QgsDataSourceURI( layer->source() ).connectionInfo();
45+
46+
if ( mConnString.isEmpty() )
47+
{
48+
mConnString = connString;
49+
mProviderKey = layer->providerType();
50+
}
51+
else if ( mConnString != connString || mProviderKey != layer->providerType() )
52+
{
53+
return false;
54+
}
55+
56+
mLayers.insert( layer );
57+
58+
connect( layer, SIGNAL( beforeEditingStarted() ), this, SLOT( onEditingStarted() ) );
59+
connect( layer, SIGNAL( layerDeleted() ), this, SLOT( onLayerDeleted() ) );
60+
61+
return true;
62+
}
63+
64+
void QgsTransactionGroup::onEditingStarted()
65+
{
66+
if ( mTransaction )
67+
return;
68+
69+
mTransaction = QgsTransaction::create( mConnString, mProviderKey );
70+
71+
QString errorMsg;
72+
mTransaction->begin( errorMsg );
73+
74+
Q_FOREACH ( QgsVectorLayer* layer, mLayers )
75+
{
76+
mTransaction->addLayer( layer );
77+
layer->startEditing();
78+
connect( layer, SIGNAL( beforeCommitChanges() ), this, SLOT( onCommitChanges() ) );
79+
connect( layer, SIGNAL( beforeRollBack() ), this, SLOT( onRollback() ) );
80+
}
81+
}
82+
83+
void QgsTransactionGroup::onLayerDeleted()
84+
{
85+
mLayers.remove( qobject_cast<QgsVectorLayer*>( sender() ) );
86+
}
87+
88+
void QgsTransactionGroup::onCommitChanges()
89+
{
90+
if ( mEditingStopping )
91+
return;
92+
93+
mEditingStopping = true;
94+
95+
QgsVectorLayer* triggeringLayer = qobject_cast<QgsVectorLayer*>( sender() );
96+
97+
QString errMsg;
98+
if ( mTransaction->commit( errMsg ) )
99+
{
100+
Q_FOREACH ( QgsVectorLayer* layer, mLayers )
101+
{
102+
if ( layer != sender() )
103+
layer->commitChanges();
104+
}
105+
}
106+
else
107+
{
108+
emit commitError( errMsg );
109+
// Restart editing the calling layer in the next event loop cycle
110+
QTimer::singleShot( 0, triggeringLayer, SLOT( startEditing() ) );
111+
}
112+
mEditingStopping = false;
113+
}
114+
115+
void QgsTransactionGroup::onRollback()
116+
{
117+
if ( mEditingStopping )
118+
return;
119+
120+
mEditingStopping = true;
121+
122+
QgsVectorLayer* triggeringLayer = qobject_cast<QgsVectorLayer*>( sender() );
123+
124+
QString errMsg;
125+
if ( mTransaction->rollback( errMsg ) )
126+
{
127+
Q_FOREACH ( QgsVectorLayer* layer, mLayers )
128+
{
129+
if ( layer != triggeringLayer )
130+
layer->rollBack();
131+
}
132+
}
133+
else
134+
{
135+
// Restart editing the calling layer in the next event loop cycle
136+
QTimer::singleShot( 0, triggeringLayer, SLOT( startEditing() ) );
137+
}
138+
mEditingStopping = false;
139+
}
140+
141+
QString QgsTransactionGroup::providerKey() const
142+
{
143+
return mProviderKey;
144+
}
145+
146+
bool QgsTransactionGroup::isEmpty() const
147+
{
148+
return mLayers.isEmpty();
149+
}
150+
151+
QString QgsTransactionGroup::connString() const
152+
{
153+
return mConnString;
154+
}

‎src/core/qgstransactiongroup.h

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/***************************************************************************
2+
qgstransactiongroup.h - QgsTransactionGroup
3+
4+
---------------------
5+
begin : 15.1.2016
6+
copyright : (C) 2016 by Matthias Kuhn
7+
email : mmatthias@opengis.ch
8+
***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
#ifndef QGSTRANSACTIONGROUP_H
17+
#define QGSTRANSACTIONGROUP_H
18+
19+
#include <QObject>
20+
#include <QSet>
21+
22+
class QgsVectorLayer;
23+
class QgsTransaction;
24+
25+
class CORE_EXPORT QgsTransactionGroup : public QObject
26+
{
27+
Q_OBJECT
28+
public:
29+
explicit QgsTransactionGroup( QObject *parent = 0 );
30+
31+
~QgsTransactionGroup();
32+
33+
/**
34+
* Add a layer to this transaction group.
35+
*
36+
* Will return true if it is compatible and has been added.
37+
*/
38+
bool addLayer( QgsVectorLayer* layer );
39+
40+
/**
41+
* Return the connection string used by this transaction group.
42+
* Layers need be compatible when added.
43+
*/
44+
QString connString() const;
45+
46+
/**
47+
* Return the provider key used by this transaction group.
48+
* Layers need be compatible when added.
49+
*/
50+
QString providerKey() const;
51+
52+
/**
53+
* Returns true if there are no layers in this transaction group.
54+
*/
55+
bool isEmpty() const;
56+
57+
signals:
58+
/**
59+
* Will be emitted whenever there is a commit error
60+
*/
61+
void commitError( const QString& msg );
62+
63+
private slots:
64+
void onEditingStarted();
65+
void onLayerDeleted();
66+
void onCommitChanges();
67+
void onRollback();
68+
69+
private:
70+
bool mEditingStarting;
71+
bool mEditingStopping;
72+
73+
QSet<QgsVectorLayer*> mLayers;
74+
//! Only set while a transaction is active
75+
QgsTransaction* mTransaction;
76+
//! Layers have to be compatible with the connection string
77+
QString mConnString;
78+
QString mProviderKey;
79+
};
80+
81+
#endif // QGSTRANSACTIONGROUP_H

‎src/core/qgsvectorlayer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,8 @@ bool QgsVectorLayer::startEditing()
13131313
return false;
13141314
}
13151315

1316+
emit beforeEditingStarted();
1317+
13161318
if ( mDataProvider->transaction() )
13171319
{
13181320
mEditBuffer = new QgsVectorLayerEditPassthrough( this );

‎src/core/qgsvectorlayer.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,14 +1140,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
11401140
*/
11411141
bool setReadOnly( bool readonly = true );
11421142

1143-
/**
1144-
* Make layer editable.
1145-
* This starts an edit session on this layer. Changes made in this edit session will not
1146-
* be made persistent until {@link commitChanges()} is called and can be reverted by calling
1147-
* {@link rollBack()}.
1148-
*/
1149-
bool startEditing();
1150-
11511143
/** Change feature's geometry */
11521144
bool changeGeometry( QgsFeatureId fid, QgsGeometry* geom );
11531145

@@ -1672,6 +1664,15 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
16721664
/** Check if there is a join with a layer that will be removed */
16731665
void checkJoinLayerRemove( const QString& theLayerId );
16741666

1667+
/**
1668+
* Make layer editable.
1669+
* This starts an edit session on this layer. Changes made in this edit session will not
1670+
* be made persistent until {@link commitChanges()} is called and can be reverted by calling
1671+
* {@link rollBack()}.
1672+
*/
1673+
bool startEditing();
1674+
1675+
16751676
protected slots:
16761677
void invalidateSymbolCountedFlag();
16771678

@@ -1695,6 +1696,9 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
16951696
/** Is emitted, when layer is checked for modifications. Use for last-minute additions */
16961697
void beforeModifiedCheck() const;
16971698

1699+
/** Is emitted, before editing on this layer is started */
1700+
void beforeEditingStarted();
1701+
16981702
/** Is emitted, when editing on this layer has started*/
16991703
void editingStarted();
17001704

‎src/core/qgsvectorlayereditpassthrough.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class CORE_EXPORT QgsVectorLayerEditPassthrough : public QgsVectorLayerEditBuffe
2424
Q_OBJECT
2525
public:
2626
QgsVectorLayerEditPassthrough( QgsVectorLayer* layer ) { L = layer; }
27-
bool isModified() const override { return false; }
27+
bool isModified() const override { return true; }
2828
bool addFeature( QgsFeature& f ) override;
2929
bool addFeatures( QgsFeatureList& features ) override;
3030
bool deleteFeature( QgsFeatureId fid ) override;

‎src/ui/qgsoptionsbase.ui

Lines changed: 271 additions & 57 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.