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
# 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.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)"

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
%End
bool autoTransaction() const;
bool autoTransaction() const /Deprecated/;
%Docstring
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.
.. versionadded:: 2.16
.. deprecated::
QGIS 3.24 use transactionMode instead
%End
void setAutoTransaction( bool autoTransaction );
void setAutoTransaction( bool autoTransaction ) /Deprecated/;
%Docstring
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
@ -865,6 +868,29 @@ transaction.
Make sure that this is only called when all layers are not in edit mode.
.. 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

View File

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

View File

@ -168,6 +168,13 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
mAreaUnitsCombo->addItem( tr( "Square Degrees" ), QgsUnitTypes::AreaSquareDegrees );
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 );
connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, this, &QgsProjectProperties::apply );
@ -242,8 +249,8 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
{
if ( layer->isEditable() )
{
mAutoTransaction->setEnabled( false );
mAutoTransaction->setToolTip( tr( "Layers are in edit mode. Stop edit mode on all layers to toggle transactional editing." ) );
mTransactionModeComboBox->setEnabled( false );
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() );
mEndDateTimeEdit->setDateTime( range.end() );
mAutoTransaction->setChecked( QgsProject::instance()->autoTransaction() );
title( QgsProject::instance()->title() );
mProjectFileLineEdit->setText( QDir::toNativeSeparators( !QgsProject::instance()->fileName().isEmpty() ? QgsProject::instance()->fileName() : QgsProject::instance()->originalPath() ) );
mProjectHomeLineEdit->setShowClearButton( true );
@ -958,7 +964,7 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
}
mRelationManagerDlg->setLayers( vectorLayers );
mAutoTransaction->setChecked( QgsProject::instance()->autoTransaction() );
mTransactionModeComboBox->setCurrentIndex( mTransactionModeComboBox->findData( static_cast<int>( QgsProject::instance()->transactionMode() ) ) );
mEvaluateDefaultValues->setChecked( QgsProject::instance()->evaluateDefaultValues() );
mTrustProjectCheckBox->setChecked( QgsProject::instance()->trustLayerMetadata() );
@ -1091,7 +1097,7 @@ void QgsProjectProperties::apply()
QgsProject::instance()->setPresetHomePath( QDir::fromNativeSeparators( mProjectHomeLineEdit->text() ) );
// DB-related options
QgsProject::instance()->setAutoTransaction( mAutoTransaction->isChecked() );
QgsProject::instance()->setTransactionMode( mTransactionModeComboBox->currentData().value<Qgis::TransactionMode>() );
QgsProject::instance()->setEvaluateDefaultValues( mEvaluateDefaultValues->isChecked() );
QgsProject::instance()->setTrustLayerMetadata( mTrustProjectCheckBox->isChecked() );

View File

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

View File

@ -890,8 +890,9 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
* transaction.
*
* \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
@ -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.
*
* \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
@ -2107,7 +2127,7 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
QColor mSelectionColor;
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
QgsCoordinateReferenceSystem mCrs;
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 )
/*
* 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.
*

View File

@ -1472,18 +1472,8 @@
</layout>
</widget>
<widget class="QWidget" name="mTab_DataSources">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0" colspan="2">
<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">
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0" colspan="3">
<widget class="QCheckBox" name="mEvaluateDefaultValues">
<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>
@ -1493,7 +1483,14 @@
</property>
</widget>
</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">
<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>
@ -1503,7 +1500,10 @@
</property>
</widget>
</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">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
@ -1570,6 +1570,19 @@
</layout>
</widget>
</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>
</widget>
<widget class="QWidget" name="mTabRelations">
@ -3344,7 +3357,6 @@
<tabstop>mButtonPasteColors</tabstop>
<tabstop>mButtonImportColors</tabstop>
<tabstop>mButtonExportColors</tabstop>
<tabstop>mAutoTransaction</tabstop>
<tabstop>mEvaluateDefaultValues</tabstop>
<tabstop>mTrustProjectCheckBox</tabstop>
<tabstop>mLayerCapabilitiesTree</tabstop>