Transaction mode setting gui

This commit is contained in:
Damiano Lombardi 2021-12-14 10:39:53 +01:00
parent 9531da1af0
commit ab3f2fca8a
8 changed files with 175 additions and 41 deletions

View File

@ -1328,6 +1328,13 @@ Qgis.FieldDomainType.__doc__ = 'Types of field domain\n\n.. versionadded:: 3.26\
# -- # --
Qgis.FieldDomainType.baseClass = Qgis Qgis.FieldDomainType.baseClass = Qgis
# monkey patching scoped based enum # monkey patching scoped based enum
Qgis.TransactionMode.None.__doc__ = ""
Qgis.TransactionMode.AutomaticGroups.__doc__ = ""
Qgis.TransactionMode.BufferedGroups.__doc__ = ""
Qgis.TransactionMode.__doc__ = 'BufferedGroups = 2, /*!< Buffered transactional editing means that all editable layers in the\nbuffered transaction group are toggled synchronously and all edits are\nsaved in a local edit buffer. Saving changes is executed within a single\ntransaction on all layers (per provider). *\n\n' + '* ``None``: ' + Qgis.TransactionMode.None.__doc__ + '\n' + '* ``AutomaticGroups``: ' + Qgis.TransactionMode.AutomaticGroups.__doc__ + '\n' + '* ``BufferedGroups``: ' + Qgis.TransactionMode.BufferedGroups.__doc__
# --
Qgis.TransactionMode.baseClass = Qgis
# monkey patching scoped based enum
Qgis.AltitudeClamping.Absolute.__doc__ = "Elevation is taken directly from feature and is independent of terrain height (final elevation = feature elevation)" Qgis.AltitudeClamping.Absolute.__doc__ = "Elevation is taken directly from feature and is independent of terrain height (final elevation = feature elevation)"
Qgis.AltitudeClamping.Relative.__doc__ = "Elevation is relative to terrain height (final elevation = terrain elevation + feature elevation)" Qgis.AltitudeClamping.Relative.__doc__ = "Elevation is relative to terrain height (final elevation = terrain elevation + feature elevation)"
Qgis.AltitudeClamping.Terrain.__doc__ = "Elevation is clamped to terrain (final elevation = terrain elevation)" Qgis.AltitudeClamping.Terrain.__doc__ = "Elevation is clamped to terrain (final elevation = terrain elevation)"

View File

@ -847,16 +847,19 @@ Gets the list of layers which currently should not be taken into account on map
use :py:func:`QgsMapLayer.setFlags()` instead use :py:func:`QgsMapLayer.setFlags()` instead
%End %End
bool autoTransaction() const; bool autoTransaction() const /Deprecated/;
%Docstring %Docstring
Transactional editing means that on supported datasources (postgres databases) the edit state of Transactional editing means that on supported datasources (postgres databases) the edit state of
all tables that originate from the same database are synchronized and executed in a server side all tables that originate from the same database are synchronized and executed in a server side
transaction. transaction.
.. versionadded:: 2.16 .. versionadded:: 2.16
.. deprecated::
QGIS 3.24 use transactionMode instead
%End %End
void setAutoTransaction( bool autoTransaction ); void setAutoTransaction( bool autoTransaction ) /Deprecated/;
%Docstring %Docstring
Transactional editing means that on supported datasources (postgres databases) the edit state of Transactional editing means that on supported datasources (postgres databases) the edit state of
all tables that originate from the same database are synchronized and executed in a server side all tables that originate from the same database are synchronized and executed in a server side
@ -865,6 +868,29 @@ transaction.
Make sure that this is only called when all layers are not in edit mode. Make sure that this is only called when all layers are not in edit mode.
.. versionadded:: 2.16 .. versionadded:: 2.16
.. deprecated::
QGIS 3.24 use setTransactionMode instead
%End
Qgis::TransactionMode transactionMode() const;
%Docstring
Returns the transaction mode
.. seealso:: Qgis.TransactionMode
.. versionadded:: 3.24
%End
void setTransactionMode( Qgis::TransactionMode transactionMode );
%Docstring
Set transaction mode
Make sure that this is only called when all layers are not in edit mode.
.. seealso:: Qgis.TransactionMode
.. versionadded:: 3.24
%End %End

View File

@ -856,6 +856,13 @@ The development version
Glob, Glob,
}; };
enum class TransactionMode
{
None,
AutomaticGroups,
BufferedGroups,
};
enum class AltitudeClamping enum class AltitudeClamping
{ {
Absolute, Absolute,

View File

@ -168,6 +168,13 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
mAreaUnitsCombo->addItem( tr( "Square Degrees" ), QgsUnitTypes::AreaSquareDegrees ); mAreaUnitsCombo->addItem( tr( "Square Degrees" ), QgsUnitTypes::AreaSquareDegrees );
mAreaUnitsCombo->addItem( tr( "Map Units" ), QgsUnitTypes::AreaUnknownUnit ); mAreaUnitsCombo->addItem( tr( "Map Units" ), QgsUnitTypes::AreaUnknownUnit );
mTransactionModeComboBox->addItem( tr( "Local edit buffer" ), static_cast< int >( Qgis::TransactionMode::None ) );
mTransactionModeComboBox->setItemData( mTransactionModeComboBox->count() - 1, tr( "Edits are buffered locally and sent to the provider when togglinglayer editing mode." ), Qt::ToolTipRole );
mTransactionModeComboBox->addItem( tr( "Automatic transaction groups" ), static_cast< int >( Qgis::TransactionMode::AutomaticGroups ) );
mTransactionModeComboBox->setItemData( mTransactionModeComboBox->count() - 1, tr( "Automatic transactional editing means that on supported datasources (postgres databases) the edit state of all tables that originate from the same database are synchronized and executed in a server side transaction." ), Qt::ToolTipRole );
mTransactionModeComboBox->addItem( tr( "Buffered transaction groups" ), static_cast< int >( Qgis::TransactionMode::None ) );
mTransactionModeComboBox->setItemData( mTransactionModeComboBox->count() - 1, tr( "Buffered transactional editing means that all editable layers in the buffered transaction group are toggled synchronously and all edits are saved in a local edit buffer. Saving changes is executed within a single transaction on all layers (per provider)." ), Qt::ToolTipRole );
projectionSelector->setShowNoProjection( true ); projectionSelector->setShowNoProjection( true );
connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, this, &QgsProjectProperties::apply ); connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, this, &QgsProjectProperties::apply );
@ -242,8 +249,8 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
{ {
if ( layer->isEditable() ) if ( layer->isEditable() )
{ {
mAutoTransaction->setEnabled( false ); mTransactionModeComboBox->setEnabled( false );
mAutoTransaction->setToolTip( tr( "Layers are in edit mode. Stop edit mode on all layers to toggle transactional editing." ) ); mTransactionModeComboBox->setToolTip( tr( "Layers are in edit mode. Stop edit mode on all layers to toggle transactional editing." ) );
} }
} }
@ -258,7 +265,6 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
mStartDateTimeEdit->setDateTime( range.begin() ); mStartDateTimeEdit->setDateTime( range.begin() );
mEndDateTimeEdit->setDateTime( range.end() ); mEndDateTimeEdit->setDateTime( range.end() );
mAutoTransaction->setChecked( QgsProject::instance()->autoTransaction() );
title( QgsProject::instance()->title() ); title( QgsProject::instance()->title() );
mProjectFileLineEdit->setText( QDir::toNativeSeparators( !QgsProject::instance()->fileName().isEmpty() ? QgsProject::instance()->fileName() : QgsProject::instance()->originalPath() ) ); mProjectFileLineEdit->setText( QDir::toNativeSeparators( !QgsProject::instance()->fileName().isEmpty() ? QgsProject::instance()->fileName() : QgsProject::instance()->originalPath() ) );
mProjectHomeLineEdit->setShowClearButton( true ); mProjectHomeLineEdit->setShowClearButton( true );
@ -958,7 +964,7 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
} }
mRelationManagerDlg->setLayers( vectorLayers ); mRelationManagerDlg->setLayers( vectorLayers );
mAutoTransaction->setChecked( QgsProject::instance()->autoTransaction() ); mTransactionModeComboBox->setCurrentIndex( mTransactionModeComboBox->findData( static_cast<int>( QgsProject::instance()->transactionMode() ) ) );
mEvaluateDefaultValues->setChecked( QgsProject::instance()->evaluateDefaultValues() ); mEvaluateDefaultValues->setChecked( QgsProject::instance()->evaluateDefaultValues() );
mTrustProjectCheckBox->setChecked( QgsProject::instance()->trustLayerMetadata() ); mTrustProjectCheckBox->setChecked( QgsProject::instance()->trustLayerMetadata() );
@ -1091,7 +1097,7 @@ void QgsProjectProperties::apply()
QgsProject::instance()->setPresetHomePath( QDir::fromNativeSeparators( mProjectHomeLineEdit->text() ) ); QgsProject::instance()->setPresetHomePath( QDir::fromNativeSeparators( mProjectHomeLineEdit->text() ) );
// DB-related options // DB-related options
QgsProject::instance()->setAutoTransaction( mAutoTransaction->isChecked() ); QgsProject::instance()->setTransactionMode( mTransactionModeComboBox->currentData().value<Qgis::TransactionMode>() );
QgsProject::instance()->setEvaluateDefaultValues( mEvaluateDefaultValues->isChecked() ); QgsProject::instance()->setEvaluateDefaultValues( mEvaluateDefaultValues->isChecked() );
QgsProject::instance()->setTrustLayerMetadata( mTrustProjectCheckBox->isChecked() ); QgsProject::instance()->setTrustLayerMetadata( mTrustProjectCheckBox->isChecked() );

View File

@ -820,7 +820,7 @@ void QgsProject::clear()
mSaveVersion = QgsProjectVersion(); mSaveVersion = QgsProjectVersion();
mHomePath.clear(); mHomePath.clear();
mCachedHomePath.clear(); mCachedHomePath.clear();
mAutoTransaction = false; mTransactionMode = Qgis::TransactionMode::None;
mEvaluateDefaultValues = false; mEvaluateDefaultValues = false;
mDirty = false; mDirty = false;
mTrustLayerMetadata = false; mTrustLayerMetadata = false;
@ -1586,11 +1586,20 @@ bool QgsProject::readProjectFile( const QString &filename, QgsProject::ReadFlags
} }
emit metadataChanged(); emit metadataChanged();
element = doc->documentElement().firstChildElement( QStringLiteral( "autotransaction" ) ); // Transaction mode
if ( ! element.isNull() ) element = doc->documentElement().firstChildElement( QStringLiteral( "transaction-mode" ) );
if ( !element.isNull() )
{ {
if ( element.attribute( QStringLiteral( "active" ), QStringLiteral( "0" ) ).toInt() == 1 ) mTransactionMode = static_cast<Qgis::TransactionMode>( element.attribute( QStringLiteral( "active" ), QStringLiteral( "0" ) ).toInt() );
mAutoTransaction = true; }
else
{
// maybe older project => try read autotransaction
element = doc->documentElement().firstChildElement( QStringLiteral( "autotransaction" ) );
if ( ! element.isNull() )
{
mTransactionMode = static_cast<Qgis::TransactionMode>( element.attribute( QStringLiteral( "active" ), QStringLiteral( "0" ) ).toInt() );
}
} }
element = doc->documentElement().firstChildElement( QStringLiteral( "evaluateDefaultValues" ) ); element = doc->documentElement().firstChildElement( QStringLiteral( "evaluateDefaultValues" ) );
@ -2068,7 +2077,7 @@ void QgsProject::onMapLayersAdded( const QList<QgsMapLayer *> &layers )
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ); QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
if ( vlayer ) if ( vlayer )
{ {
if ( autoTransaction() ) if ( transactionMode() == Qgis::TransactionMode::AutomaticGroups )
{ {
if ( QgsTransaction::supportsTransaction( vlayer ) ) if ( QgsTransaction::supportsTransaction( vlayer ) )
{ {
@ -2310,8 +2319,8 @@ bool QgsProject::writeProjectFile( const QString &filename )
QDomElement titleNode = doc->createElement( QStringLiteral( "title" ) ); QDomElement titleNode = doc->createElement( QStringLiteral( "title" ) );
qgisNode.appendChild( titleNode ); qgisNode.appendChild( titleNode );
QDomElement transactionNode = doc->createElement( QStringLiteral( "autotransaction" ) ); QDomElement transactionNode = doc->createElement( QStringLiteral( "transaction-mode" ) );
transactionNode.setAttribute( QStringLiteral( "active" ), mAutoTransaction ? 1 : 0 ); transactionNode.setAttribute( QStringLiteral( "active" ), QString::number( static_cast<int>( mTransactionMode ) ) );
qgisNode.appendChild( transactionNode ); qgisNode.appendChild( transactionNode );
QDomElement evaluateDefaultValuesNode = doc->createElement( QStringLiteral( "evaluateDefaultValues" ) ); QDomElement evaluateDefaultValuesNode = doc->createElement( QStringLiteral( "evaluateDefaultValues" ) );
@ -3302,20 +3311,47 @@ QStringList QgsProject::nonIdentifiableLayers() const
bool QgsProject::autoTransaction() const bool QgsProject::autoTransaction() const
{ {
return mAutoTransaction; return mTransactionMode == Qgis::TransactionMode::AutomaticGroups;
} }
void QgsProject::setAutoTransaction( bool autoTransaction ) void QgsProject::setAutoTransaction( bool autoTransaction )
{ {
if ( autoTransaction != mAutoTransaction ) if ( autoTransaction
{ && mTransactionMode == Qgis::TransactionMode::AutomaticGroups )
mAutoTransaction = autoTransaction; return;
if ( autoTransaction ) if ( ! autoTransaction
onMapLayersAdded( mapLayers().values() ); && mTransactionMode == Qgis::TransactionMode::None )
else return;
cleanTransactionGroups( true );
if ( autoTransaction )
{
mTransactionMode = Qgis::TransactionMode::AutomaticGroups;
onMapLayersAdded( mapLayers().values() );
} }
else
{
mTransactionMode = Qgis::TransactionMode::None;
cleanTransactionGroups( true );
}
}
Qgis::TransactionMode QgsProject::transactionMode() const
{
return mTransactionMode;
}
void QgsProject::setTransactionMode( Qgis::TransactionMode transactionMode )
{
if ( transactionMode == mTransactionMode )
return;
mTransactionMode = transactionMode;
if ( mTransactionMode == Qgis::TransactionMode::AutomaticGroups )
onMapLayersAdded( mapLayers().values() );
else
cleanTransactionGroups( true );
} }
QMap<QPair<QString, QString>, QgsTransactionGroup *> QgsProject::transactionGroups() QMap<QPair<QString, QString>, QgsTransactionGroup *> QgsProject::transactionGroups()

View File

@ -890,8 +890,9 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
* transaction. * transaction.
* *
* \since QGIS 2.16 * \since QGIS 2.16
* \deprecated QGIS 3.24 use transactionMode instead
*/ */
bool autoTransaction() const; Q_DECL_DEPRECATED bool autoTransaction() const SIP_DEPRECATED;
/** /**
* Transactional editing means that on supported datasources (postgres databases) the edit state of * Transactional editing means that on supported datasources (postgres databases) the edit state of
@ -901,8 +902,27 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
* Make sure that this is only called when all layers are not in edit mode. * Make sure that this is only called when all layers are not in edit mode.
* *
* \since QGIS 2.16 * \since QGIS 2.16
* \deprecated QGIS 3.24 use setTransactionMode instead
*/ */
void setAutoTransaction( bool autoTransaction ); Q_DECL_DEPRECATED void setAutoTransaction( bool autoTransaction ) SIP_DEPRECATED;
/**
* Returns the transaction mode
*
* \see Qgis::TransactionMode
* \since QGIS 3.24
*/
Qgis::TransactionMode transactionMode() const;
/**
* Set transaction mode
*
* Make sure that this is only called when all layers are not in edit mode.
*
* \see Qgis::TransactionMode
* \since QGIS 3.24
*/
void setTransactionMode( Qgis::TransactionMode transactionMode );
/** /**
* Map of transaction groups * Map of transaction groups
@ -2107,7 +2127,7 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
QColor mSelectionColor; QColor mSelectionColor;
mutable QgsProjectPropertyKey mProperties; // property hierarchy, TODO: this shouldn't be mutable mutable QgsProjectPropertyKey mProperties; // property hierarchy, TODO: this shouldn't be mutable
bool mAutoTransaction = false; // transaction grouped editing Qgis::TransactionMode mTransactionMode = Qgis::TransactionMode::None; // transaction grouped editing
bool mEvaluateDefaultValues = false; // evaluate default values immediately bool mEvaluateDefaultValues = false; // evaluate default values immediately
QgsCoordinateReferenceSystem mCrs; QgsCoordinateReferenceSystem mCrs;
bool mDirty = false; // project has been modified since it has been read or saved bool mDirty = false; // project has been modified since it has been read or saved

View File

@ -1410,6 +1410,26 @@ class CORE_EXPORT Qgis
}; };
Q_ENUM( FieldDomainType ) Q_ENUM( FieldDomainType )
/*
* Transaction mode.
*
* \since QGIS 3.24
*/
enum class TransactionMode : int
{
None = 0, /*!< Edits are buffered locally and sent to the provider when toggling
* layer editing mode. */
AutomaticGroups = 1, /*!< Automatic transactional editing means that on supported datasources
* (postgres databases) the edit state of all tables that originate from
* the same database are synchronized and executed in a server side
* transaction. */
BufferedGroups = 2, /*!< Buffered transactional editing means that all editable layers in the
* buffered transaction group are toggled synchronously and all edits are
* saved in a local edit buffer. Saving changes is executed within a single
* transaction on all layers (per provider). */
};
Q_ENUM( TransactionMode )
/** /**
* Altitude clamping. * Altitude clamping.
* *

View File

@ -1472,18 +1472,8 @@
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="mTab_DataSources"> <widget class="QWidget" name="mTab_DataSources">
<layout class="QFormLayout" name="formLayout"> <layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="2"> <item row="1" column="0" colspan="3">
<widget class="QCheckBox" name="mAutoTransaction">
<property name="toolTip">
<string>When enabled, layers from the same database connection will be put into a transaction group. Their edit state will be synchronized and changes to these layers will be sent to the provider immediately. Only supported for postgres, GPKG, spatialite and oracle.</string>
</property>
<property name="text">
<string>Automatically create transaction groups where possible</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="mEvaluateDefaultValues"> <widget class="QCheckBox" name="mEvaluateDefaultValues">
<property name="toolTip"> <property name="toolTip">
<string>When enabled, default values will be evaluated as early as possible. This will fill default values in the add feature form already and not only create them on commit. Only supported for postgres, GPKG, spatialite and oracle.</string> <string>When enabled, default values will be evaluated as early as possible. This will fill default values in the add feature form already and not only create them on commit. Only supported for postgres, GPKG, spatialite and oracle.</string>
@ -1493,7 +1483,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label_37">
<property name="text">
<string>Transaction mode</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QCheckBox" name="mTrustProjectCheckBox"> <widget class="QCheckBox" name="mTrustProjectCheckBox">
<property name="toolTip"> <property name="toolTip">
<string>Speed up project loading by skipping data checks in PostgreSQL layers. Useful in QGIS server context or project with huge database views or materialized views.</string> <string>Speed up project loading by skipping data checks in PostgreSQL layers. Useful in QGIS server context or project with huge database views or materialized views.</string>
@ -1503,7 +1500,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0" colspan="2"> <item row="0" column="1">
<widget class="QComboBox" name="mTransactionModeComboBox"/>
</item>
<item row="3" column="0" colspan="3">
<widget class="QgsCollapsibleGroupBox" name="groupBox_5"> <widget class="QgsCollapsibleGroupBox" name="groupBox_5">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
@ -1570,6 +1570,19 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="0" column="2">
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="mTabRelations"> <widget class="QWidget" name="mTabRelations">
@ -3344,7 +3357,6 @@
<tabstop>mButtonPasteColors</tabstop> <tabstop>mButtonPasteColors</tabstop>
<tabstop>mButtonImportColors</tabstop> <tabstop>mButtonImportColors</tabstop>
<tabstop>mButtonExportColors</tabstop> <tabstop>mButtonExportColors</tabstop>
<tabstop>mAutoTransaction</tabstop>
<tabstop>mEvaluateDefaultValues</tabstop> <tabstop>mEvaluateDefaultValues</tabstop>
<tabstop>mTrustProjectCheckBox</tabstop> <tabstop>mTrustProjectCheckBox</tabstop>
<tabstop>mLayerCapabilitiesTree</tabstop> <tabstop>mLayerCapabilitiesTree</tabstop>