Skip to content

Commit

Permalink
Merge branch 'master' of github.com:qgis/QGIS
Browse files Browse the repository at this point in the history
  • Loading branch information
pcav committed Jan 29, 2018
2 parents 3b39dcf + aec399e commit 5b8bea7
Show file tree
Hide file tree
Showing 27 changed files with 491 additions and 58 deletions.
46 changes: 45 additions & 1 deletion python/core/qgsvectorlayer.sip.in
Expand Up @@ -1483,7 +1483,7 @@ QVariant is used (the default behavior), then the feature's current value will b
retrieved and used. Note that this involves a feature request to the underlying data provider,
so it is more efficient to explicitly pass an ``oldValue`` if it is already available.

If ``skipDefaultValue`` is set to true, default field values will not
If ``skipDefaultValues`` is set to true, default field values will not
be updated. This can be used to override default field value expressions.

Returns true if the feature's attribute was successfully changed.
Expand All @@ -1502,6 +1502,50 @@ Returns true if the feature's attribute was successfully changed.
.. seealso:: :py:func:`changeGeometry`

.. seealso:: :py:func:`updateFeature`
%End

bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap(), bool skipDefaultValues = false );
%Docstring
Changes attributes' values for a feature (but does not immediately
commit the changes).
The ``fid`` argument specifies the ID of the feature to be changed.

The new values to be assigned to the fields are given by ``newValues``.

If a valid QVariant is specified for a field in ``oldValues``, it will be
used as the field value in the case of an undo operation corresponding
to this attribute value change. If an invalid QVariant is used (the
default behavior), then the feature's current value will be
automatically retrieved and used. Note that this involves a feature
request to the underlying data provider, so it is more efficient to
explicitly pass an oldValue if it is already available.

If ``skipDefaultValues`` is set to true, default field values will not
be updated. This can be used to override default field value
expressions.

Returns true if feature's attributes was successfully changed.

.. note::

Calls to changeAttributeValues() are only valid for layers in
which edits have been enabled by a call to startEditing(). Changes made
to features using this method are not committed to the underlying data
provider until a commitChanges() call is made. Any uncommitted changes
can be discarded by calling rollBack().

.. seealso:: :py:func:`startEditing`

.. seealso:: :py:func:`commitChanges`

.. seealso:: :py:func:`changeGeometry`

.. seealso:: :py:func:`updateFeature`

.. seealso:: :py:func:`changeAttributeValue`


.. versionadded:: 3.0
%End

bool addAttribute( const QgsField &field );
Expand Down
9 changes: 9 additions & 0 deletions python/core/qgsvectorlayereditbuffer.sip.in
Expand Up @@ -58,6 +58,15 @@ Change feature's geometry
virtual bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() );
%Docstring
Changed an attribute value (but does not commit it)
%End

virtual bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues );
%Docstring
Changes values of attributes (but does not commit it).

:return: true if attributes are well updated, false otherwise

.. versionadded:: 3.0
%End

virtual bool addAttribute( const QgsField &field );
Expand Down
11 changes: 11 additions & 0 deletions python/core/qgsvectorlayereditpassthrough.sip.in
Expand Up @@ -30,6 +30,17 @@ class QgsVectorLayerEditPassthrough : QgsVectorLayerEditBuffer

virtual bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() );


virtual bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues );

%Docstring
Changes values of attributes (but does not commit it).

:return: true if attributes are well updated, false otherwise

.. versionadded:: 3.0
%End

virtual bool addAttribute( const QgsField &field );

virtual bool deleteAttribute( int attr );
Expand Down
17 changes: 17 additions & 0 deletions python/core/qgsvectorlayerjoinbuffer.sip.in
Expand Up @@ -185,6 +185,23 @@ created if its fields are not empty.
:return: false if an error happened, true otherwise


.. versionadded:: 3.0
%End

bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap() );
%Docstring
Changes attributes' values in joined layers. The feature id given in
parameter is the one added in target layer. If the corresponding joined
feature does not exist in a joined layer, then it's automatically
created if its fields are not empty.

:param fid: The feature id
:param newValues: The new values for attributes
:param oldValues: The old values for attributes

:return: false if an error happened, true otherwise


.. versionadded:: 3.0
%End

Expand Down
31 changes: 31 additions & 0 deletions python/core/qgsvectorlayerundopassthroughcommand.sip.in
Expand Up @@ -202,6 +202,37 @@ Constructor for QgsVectorLayerUndoPassthroughCommandChangeAttribute
};


class QgsVectorLayerUndoPassthroughCommandChangeAttributes: QgsVectorLayerUndoPassthroughCommand
{
%Docstring
Undo command for changing attributes' values from a vector layer in transaction group.

.. versionadded:: 3.0
%End

%TypeHeaderCode
#include "qgsvectorlayerundopassthroughcommand.h"
%End
public:

QgsVectorLayerUndoPassthroughCommandChangeAttributes( QgsVectorLayerEditBuffer *buffer /Transfer/, QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap() );
%Docstring
Constructor for QgsVectorLayerUndoPassthroughCommandChangeAttributes

:param buffer: associated edit buffer
:param fid: feature ID of feature
:param newValues: New values for attributes
:param oldValues: Old values for attributes
%End

virtual void undo();

virtual void redo();


};


class QgsVectorLayerUndoPassthroughCommandAddAttribute : QgsVectorLayerUndoPassthroughCommand
{
%Docstring
Expand Down
Expand Up @@ -40,6 +40,10 @@ Executes the single band pseudo raster classficiation
void loadMinMax( int bandNo, double min, double max );
%Docstring
called when new min/max values are loaded
%End
void loadMinMaxFromTree();
%Docstring
called when the color ramp tree has changed
%End

};
Expand Down
6 changes: 0 additions & 6 deletions src/app/nodetool/qgsnodeeditor.cpp
Expand Up @@ -68,7 +68,6 @@ QgsNodeEditorModel::QgsNodeEditorModel( QgsVectorLayer *layer, QgsSelectedFeatur
mWidgetFont = parentWidget->font();
}

connect( mSelectedFeature, &QgsSelectedFeature::vertexMapChanged, this, &QgsNodeEditorModel::featureChanged );
}

int QgsNodeEditorModel::rowCount( const QModelIndex &parent ) const
Expand Down Expand Up @@ -273,11 +272,6 @@ bool QgsNodeEditorModel::calcR( int row, double &r, double &minRadius ) const
return true;
}

void QgsNodeEditorModel::featureChanged()
{
//TODO - avoid reset
reset();
}

QgsNodeEditor::QgsNodeEditor(
QgsVectorLayer *layer,
Expand Down
3 changes: 0 additions & 3 deletions src/app/nodetool/qgsnodeeditor.h
Expand Up @@ -64,9 +64,6 @@ class QgsNodeEditorModel : public QAbstractTableModel

bool calcR( int row, double &r, double &minRadius ) const;

private slots:

void featureChanged();
};

class QgsNodeEditor : public QgsDockWidget
Expand Down
18 changes: 15 additions & 3 deletions src/app/qgisapp.cpp
Expand Up @@ -12613,9 +12613,21 @@ void QgisApp::showLayerProperties( QgsMapLayer *ml )
#else
QgsRasterLayerProperties *rlp = new QgsRasterLayerProperties( ml, mMapCanvas, this );
#endif

rlp->exec();
delete rlp; // delete since dialog cannot be reused without updating code
// Cannot use exec here due to raster transparency map tool:
// in order to pass focus to the canvas, the dialog needs to
// be hidden and shown in non-modal mode.
rlp->setModal( true );
rlp->show();
// Delete (later, for safety) since dialog cannot be reused without
// updating code
connect( rlp, &QgsRasterLayerProperties::accepted, [ rlp ]
{
rlp->deleteLater();
} );
connect( rlp, &QgsRasterLayerProperties::rejected, [ rlp ]
{
rlp->deleteLater();
} );
}
else if ( ml->type() == QgsMapLayer::VectorLayer ) // VECTOR
{
Expand Down
28 changes: 13 additions & 15 deletions src/app/qgsrasterlayerproperties.cpp
Expand Up @@ -176,11 +176,10 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanv
pbnImportTransparentPixelValues->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionFileOpen.svg" ) ) );
pbnExportTransparentPixelValues->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionFileSave.svg" ) ) );

mPixelSelectorTool = nullptr;
if ( mMapCanvas )
{
mPixelSelectorTool = new QgsMapToolEmitPoint( canvas );
connect( mPixelSelectorTool, &QgsMapToolEmitPoint::canvasClicked, this, &QgsRasterLayerProperties::pixelSelected );
mPixelSelectorTool = qgis::make_unique<QgsMapToolEmitPoint>( canvas );
connect( mPixelSelectorTool.get(), &QgsMapToolEmitPoint::canvasClicked, this, &QgsRasterLayerProperties::pixelSelected );
}
else
{
Expand Down Expand Up @@ -455,10 +454,6 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanv

QgsRasterLayerProperties::~QgsRasterLayerProperties()
{
if ( mPixelSelectorTool )
{
delete mPixelSelectorTool;
}
}

void QgsRasterLayerProperties::setupTransparencyTable( int nBands )
Expand Down Expand Up @@ -1197,16 +1192,18 @@ void QgsRasterLayerProperties::pbnAddValuesFromDisplay_clicked()
{
if ( mMapCanvas && mPixelSelectorTool )
{
mMapCanvas->setMapTool( mPixelSelectorTool );
//Need to work around the modality of the dialog but can not just hide() it.
// According to Qt5 docs, to change modality the dialog needs to be hidden
// and shown it again.
hide();
setModal( false );

showMinimized();

//Q_ASSERT( parentWidget()->parentWidget() );
parentWidget()->activateWindow();
parentWidget()->raise();
//lower();
// Transfer focus to the canvas to use the selector tool
mMapCanvas->window()->raise();
mMapCanvas->window()->activateWindow();
mMapCanvas->window()->setFocus();
mMapCanvas->setMapTool( mPixelSelectorTool.get() );
}
}

Expand Down Expand Up @@ -1630,8 +1627,9 @@ void QgsRasterLayerProperties::pbnRemoveSelectedRow_clicked()
}
}

void QgsRasterLayerProperties::pixelSelected( const QgsPointXY &canvasPoint )
void QgsRasterLayerProperties::pixelSelected( const QgsPointXY &canvasPoint, const Qt::MouseButton &btn )
{
Q_UNUSED( btn );
QgsRasterRenderer *renderer = mRendererWidget->renderer();
if ( !renderer )
{
Expand All @@ -1645,7 +1643,7 @@ void QgsRasterLayerProperties::pixelSelected( const QgsPointXY &canvasPoint )
//Get the pixel values and add a new entry to the transparency table
if ( mMapCanvas && mPixelSelectorTool )
{
mMapCanvas->unsetMapTool( mPixelSelectorTool );
mMapCanvas->unsetMapTool( mPixelSelectorTool.get() );

const QgsMapSettings &ms = mMapCanvas->mapSettings();
QgsPointXY myPoint = ms.mapToLayerCoordinates( mRasterLayer, canvasPoint );
Expand Down
6 changes: 3 additions & 3 deletions src/app/qgsrasterlayerproperties.h
Expand Up @@ -26,13 +26,13 @@
#include "qgsguiutils.h"
#include "qgshelp.h"
#include "qgsmaplayerstylemanager.h"
#include "qgsmaptoolemitpoint.h"
#include "qgis_app.h"

class QgsPointXY;
class QgsMapLayer;
class QgsMapCanvas;
class QgsRasterLayer;
class QgsMapToolEmitPoint;
class QgsMetadataWidget;
class QgsRasterRenderer;
class QgsRasterRendererWidget;
Expand Down Expand Up @@ -91,7 +91,7 @@ class APP_EXPORT QgsRasterLayerProperties : public QgsOptionsDialogBase, private
*/
//void on_btnResetNull_clicked();

void pixelSelected( const QgsPointXY & );
void pixelSelected( const QgsPointXY &, const Qt::MouseButton & );

private slots:
void mRenderTypeComboBox_currentIndexChanged( int index );
Expand Down Expand Up @@ -206,7 +206,7 @@ class APP_EXPORT QgsRasterLayerProperties : public QgsOptionsDialogBase, private
qreal mGradientWidth;

QgsMapCanvas *mMapCanvas = nullptr;
QgsMapToolEmitPoint *mPixelSelectorTool = nullptr;
std::unique_ptr<QgsMapToolEmitPoint> mPixelSelectorTool;

QgsRasterHistogramWidget *mHistogramWidget = nullptr;

Expand Down
58 changes: 58 additions & 0 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -2387,6 +2387,64 @@ bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QV
return result;
}

bool QgsVectorLayer::changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues, bool skipDefaultValues )
{
bool result = true;

QgsAttributeMap newValuesJoin;
QgsAttributeMap oldValuesJoin;

QgsAttributeMap newValuesNotJoin;
QgsAttributeMap oldValuesNotJoin;

for ( auto it = newValues.constBegin(); it != newValues.constEnd(); ++it )
{
const int field = it.key();
const QVariant newValue = it.value();
QVariant oldValue;

if ( oldValues.contains( field ) )
oldValue = oldValues[field];

switch ( fields().fieldOrigin( field ) )
{
case QgsFields::OriginJoin:
newValuesJoin[field] = newValue;
oldValuesJoin[field] = oldValue;
break;

case QgsFields::OriginProvider:
case QgsFields::OriginEdit:
case QgsFields::OriginExpression:
{
newValuesNotJoin[field] = newValue;
oldValuesNotJoin[field] = oldValue;
break;
}

case QgsFields::OriginUnknown:
break;
}
}

if ( ! newValuesJoin.isEmpty() && mJoinBuffer )
{
result = mJoinBuffer->changeAttributeValues( fid, newValuesJoin, oldValuesJoin );
}

if ( ! newValuesNotJoin.isEmpty() && mEditBuffer && mDataProvider )
{
result &= mEditBuffer->changeAttributeValues( fid, newValues, oldValues );
}

if ( result && !skipDefaultValues && !mDefaultValueOnUpdateFields.isEmpty() )
{
updateDefaultValues( fid );
}

return result;
}

bool QgsVectorLayer::addAttribute( const QgsField &field )
{
if ( !mEditBuffer || !mDataProvider )
Expand Down

0 comments on commit 5b8bea7

Please sign in to comment.