Skip to content
Permalink
Browse files

[FIX] - Respect selection order in attribute table copy. (#8048)

Only copy fields shown in view for current table.
  • Loading branch information
NathanW2 committed Oct 8, 2018
1 parent 556cddd commit f928c2e5454067729da365d411fa3ec00d9aa9cb
@@ -10,6 +10,7 @@




typedef QVector< QgsPoint > QgsPointSequence;
typedef QVector< QVector< QgsPoint > > QgsRingSequence;
typedef QVector< QVector< QVector< QgsPoint > > > QgsCoordinateSequence;
@@ -13,6 +13,7 @@




typedef QVector<QgsPointXY> QgsPolylineXY;

typedef QVector<QgsPoint> QgsPolyline;
@@ -58,6 +58,15 @@ Set the attribute table config which should be used to control
the appearance of the attribute table.

.. versionadded:: 2.16
%End

QList<QgsFeatureId> selectedFeaturesIds() const;
%Docstring
Returns the selected features in the attribute table in table sorted order.

:return: The selected features in the attribute table in the order sorted by the table.

.. versionadded:: 3.4
%End

protected:
@@ -165,6 +165,13 @@ Set the expression used for sorting the table and feature list.
QString sortExpression() const;
%Docstring
Gets the expression used for sorting the table and feature list.
%End

QgsAttributeTableConfig attributeTableConfig() const;
%Docstring
The config used for the attribute table.

:return: The config used for the attribute table.
%End

public slots:
@@ -24,16 +24,24 @@ Dialog for organising (hiding and reordering) columns in the attributes table.
%End
public:

QgsOrganizeTableColumnsDialog( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0, Qt::WindowFlags flags = Qt::Window );
QgsOrganizeTableColumnsDialog( const QgsVectorLayer *vl, QgsAttributeTableConfig config, QWidget *parent /TransferThis/ = 0, Qt::WindowFlags flags = Qt::Window );
%Docstring
Constructor

:param vl: The concerned vector layer
:param parent: parent object
:param config: attribute table config to use.
:param flags: window flags
%End

~QgsOrganizeTableColumnsDialog();
QgsOrganizeTableColumnsDialog( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0, Qt::WindowFlags flags = Qt::Window );
%Docstring
Constructor

:param vl: The concerned vector layer
:param parent: parent object
:param flags: window flags
%End

QgsAttributeTableConfig config() const;
%Docstring
@@ -26,6 +26,7 @@

#include "qgsapplication.h"
#include "qgsvectorlayer.h"
#include "qgsvectorlayerutils.h"
#include "qgsvectordataprovider.h"
#include "qgsexpression.h"
#include "qgsexpressionbuilderwidget.h"
@@ -50,6 +51,8 @@
#include "qgseditorwidgetregistry.h"
#include "qgsfieldproxymodel.h"
#include "qgsgui.h"
#include "qgsclipboard.h"
#include "qgsfeaturestore.h"

QgsExpressionContext QgsAttributeTableDialog::createExpressionContext() const
{
@@ -762,7 +765,46 @@ void QgsAttributeTableDialog::mActionCutSelectedRows_triggered()

void QgsAttributeTableDialog::mActionCopySelectedRows_triggered()
{
QgisApp::instance()->copySelectionToClipboard( mLayer );
if ( mMainView->view() == QgsDualView::AttributeTable )
{
const QList<QgsFeatureId> featureIds = mMainView->tableView()->selectedFeaturesIds();
QgsFeatureStore featureStore;
QgsFields fields = QgsFields( mLayer->fields() );
QStringList fieldNames;

const auto configs = mMainView->attributeTableConfig().columns();
for ( const QgsAttributeTableConfig::ColumnConfig &columnConfig : configs )
{
if ( columnConfig.hidden )
{
int fieldIndex = fields.lookupField( columnConfig.name );
fields.remove( fieldIndex );
continue;
}
fieldNames << columnConfig.name;
}
featureStore.setFields( fields );

QgsFeatureIterator it = mLayer->getFeatures( QgsFeatureRequest( featureIds.toSet() )
.setSubsetOfAttributes( fieldNames, mLayer->fields() ) );
QgsFeatureMap featureMap;
QgsFeature feature;
while ( it.nextFeature( feature ) )
{
QgsVectorLayerUtils::matchAttributesToFields( feature, fields );
featureMap[feature.id()] = feature;
}
for ( const QgsFeatureId &id : featureIds )
{
featureStore.addFeature( featureMap[id] );
}

QgisApp::instance()->clipboard()->replaceWithCopyOf( featureStore );
}
else
{
QgisApp::instance()->copySelectionToClipboard( mLayer );
}
}

void QgsAttributeTableDialog::mActionPasteFeatures_triggered()
@@ -115,7 +115,6 @@ QString QgsClipboard::generateClipboardText() const
}
}

// QgsDebugMsg("about to traverse fields.");
for ( int idx = 0; idx < attributes.count(); ++idx )
{
// QgsDebugMsg(QString("inspecting field '%1'.").arg(it2->toString()));
@@ -104,6 +104,30 @@ void QgsAttributeTableView::setAttributeTableConfig( const QgsAttributeTableConf
}
i++;
}
mConfig = config;
}

QList<QgsFeatureId> QgsAttributeTableView::selectedFeaturesIds() const
{
// In order to get the ids in the right sorted order based on the view we have to get the feature ids first
// from the selection manager which is in the order the user selected them when clicking
// then get the model index, sort that, and finally return the new sorted features ids.
const QgsFeatureIds featureIds = mFeatureSelectionManager->selectedFeatureIds();
QModelIndexList indexList;
for ( const QgsFeatureId &id : featureIds )
{
QModelIndex index = mFilterModel->fidToIndex( id );
indexList << index;
}

std::sort( indexList.begin(), indexList.end() );
QList<QgsFeatureId> ids;
for ( const QModelIndex &index : indexList )
{
QgsFeatureId id = mFilterModel->data( index, QgsAttributeTableModel::FeatureIdRole ).toLongLong();
ids.append( id );
}
return ids;
}

void QgsAttributeTableView::setModel( QgsAttributeTableFilterModel *filterModel )
@@ -153,7 +177,7 @@ void QgsAttributeTableView::setFeatureSelectionManager( QgsIFeatureSelectionMana

QWidget *QgsAttributeTableView::createActionWidget( QgsFeatureId fid )
{
QgsAttributeTableConfig attributeTableConfig = mFilterModel->layer()->attributeTableConfig();
QgsAttributeTableConfig attributeTableConfig = mConfig;

QToolButton *toolButton = nullptr;
QWidget *container = nullptr;
@@ -22,6 +22,7 @@
#include "qgsfeatureid.h"

#include "qgis_gui.h"
#include "qgsattributetableconfig.h"

class QgsAttributeTableDelegate;
class QgsAttributeTableFilterModel;
@@ -34,6 +35,7 @@ class QgsVectorLayerCache;
class QMenu;
class QProgressDialog;
class QgsAttributeTableConfig;
class QgsFeature;

/**
* \ingroup gui
@@ -80,6 +82,13 @@ class GUI_EXPORT QgsAttributeTableView : public QTableView
*/
void setAttributeTableConfig( const QgsAttributeTableConfig &config );

/**
* Returns the selected features in the attribute table in table sorted order.
* \returns The selected features in the attribute table in the order sorted by the table.
* \since QGIS 3.4
*/
QList<QgsFeatureId> selectedFeaturesIds() const;

protected:

/**
@@ -179,6 +188,7 @@ class GUI_EXPORT QgsAttributeTableView : public QTableView
int mRowSectionAnchor = 0;
QItemSelectionModel::SelectionFlag mCtrlDragSelectionFlag = QItemSelectionModel::Select;
QMap< QModelIndex, QWidget * > mActionWidgets;
QgsAttributeTableConfig mConfig;
};

#endif
@@ -654,7 +654,7 @@ void QgsDualView::organizeColumns()
return;
}

QgsOrganizeTableColumnsDialog dialog( mLayer, this );
QgsOrganizeTableColumnsDialog dialog( mLayer, attributeTableConfig(), this );
if ( dialog.exec() == QDialog::Accepted )
{
QgsAttributeTableConfig config = dialog.config();
@@ -838,7 +838,7 @@ void QgsDualView::previewExpressionChanged( const QString &expression )

void QgsDualView::onSortColumnChanged()
{
QgsAttributeTableConfig cfg = mLayer->attributeTableConfig();
QgsAttributeTableConfig cfg = attributeTableConfig();
if ( cfg.sortExpression() != mFilterModel->sortExpression() ||
cfg.sortOrder() != mFilterModel->sortOrder() )
{
@@ -916,7 +916,6 @@ void QgsDualView::setAttributeTableConfig( const QgsAttributeTableConfig &config
{
mConfig = config;
mConfig.update( mLayer->fields() );
mLayer->setAttributeTableConfig( mConfig );
mFilterModel->setAttributeTableConfig( mConfig );
mTableView->setAttributeTableConfig( mConfig );
}
@@ -938,6 +937,11 @@ QString QgsDualView::sortExpression() const
return mFilterModel->sortExpression();
}

QgsAttributeTableConfig QgsDualView::attributeTableConfig() const
{
return mConfig;
}

void QgsDualView::progress( int i, bool &cancel )
{
if ( !mProgressDlg )
@@ -198,6 +198,12 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
*/
QString sortExpression() const;

/**
* The config used for the attribute table.
* \returns The config used for the attribute table.
*/
QgsAttributeTableConfig attributeTableConfig() const;

public slots:

/**
@@ -39,18 +39,21 @@
#include "qgsfields.h"
#include "qgseditorwidgetregistry.h"

#include "qgsgui.h"

QgsOrganizeTableColumnsDialog::QgsOrganizeTableColumnsDialog( const QgsVectorLayer *vl, QWidget *parent, Qt::WindowFlags flags )

QgsOrganizeTableColumnsDialog::QgsOrganizeTableColumnsDialog( const QgsVectorLayer *vl, QgsAttributeTableConfig config, QWidget *parent, Qt::WindowFlags flags )
: QDialog( parent, flags )
{
setupUi( this );
QgsGui::instance()->enableAutoGeometryRestore( this );

connect( mShowAllButton, &QAbstractButton::clicked, this, &QgsOrganizeTableColumnsDialog::showAll );
connect( mHideAllButton, &QAbstractButton::clicked, this, &QgsOrganizeTableColumnsDialog::hideAll );

if ( vl )
{
mConfig = vl->attributeTableConfig();
mConfig = config;
mConfig.update( vl->fields() );

mFieldsList->clear();
@@ -94,15 +97,11 @@ QgsOrganizeTableColumnsDialog::QgsOrganizeTableColumnsDialog( const QgsVectorLay
mShowAllButton->hide();
mHideAllButton->hide();
}

QgsSettings settings;
restoreGeometry( settings.value( QStringLiteral( "Windows/QgsOrganizeTableColumnsDialog/geometry" ) ).toByteArray() );
}

QgsOrganizeTableColumnsDialog::~QgsOrganizeTableColumnsDialog()
QgsOrganizeTableColumnsDialog::QgsOrganizeTableColumnsDialog( const QgsVectorLayer *vl, QWidget *parent, Qt::WindowFlags flags )
: QgsOrganizeTableColumnsDialog( vl, vl->attributeTableConfig(), parent, flags )
{
QgsSettings settings;
settings.setValue( QStringLiteral( "Windows/QgsOrganizeTableColumnsDialog/geometry" ), saveGeometry() );
}

QgsAttributeTableConfig QgsOrganizeTableColumnsDialog::config() const
@@ -42,11 +42,18 @@ class GUI_EXPORT QgsOrganizeTableColumnsDialog : public QDialog, private Ui::Qgs
* Constructor
* \param vl The concerned vector layer
* \param parent parent object
* \param config attribute table config to use.
* \param flags window flags
*/
QgsOrganizeTableColumnsDialog( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr, Qt::WindowFlags flags = Qt::Window );
QgsOrganizeTableColumnsDialog( const QgsVectorLayer *vl, QgsAttributeTableConfig config, QWidget *parent SIP_TRANSFERTHIS = nullptr, Qt::WindowFlags flags = Qt::Window );

~QgsOrganizeTableColumnsDialog() override;
/**
* Constructor
* \param vl The concerned vector layer
* \param parent parent object
* \param flags window flags
*/
QgsOrganizeTableColumnsDialog( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr, Qt::WindowFlags flags = Qt::Window );

/**
* Gets the updated configuration

0 comments on commit f928c2e

Please sign in to comment.
You can’t perform that action at this time.