Skip to content
Permalink
Browse files

Merge pull request #5961 from signedav/work_contextmenu

Contextmenu with individual actions
  • Loading branch information
m-kuhn committed Jan 8, 2018
2 parents 9e704eb + 2eaf4de commit 8392d7fe399fe21c020679ed3131a99773b37bd7
@@ -245,6 +245,14 @@ Is emitted when a filter expression is set using the view.
Emitted when the form changes mode.

:param mode: new mode
%End

void showContextMenuExternally( QgsActionMenu *menu, const QgsFeatureId fid );
%Docstring
Emitted when selecting context menu on the feature list to create the context menu individually

:param menu: context menu
:param fid: feature id of the selected feature
%End

protected:
@@ -128,6 +128,14 @@ Is emitted, whenever the display expression is successfully changed
%End


void willShowContextMenu( QgsActionMenu *menu, const QModelIndex &atIndex );
%Docstring
Is emitted, when the context menu is created to add the specific actions to it

:param menu: is the already created context menu
:param atIndex: is the position of the current feature in the model
%End

public slots:

void setEditSelection( const QgsFeatureIds &fids );
@@ -105,6 +105,7 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttr
connect( mMainView, &QgsDualView::currentChanged, this, &QgsAttributeTableDialog::mMainView_currentChanged );
connect( mActionAddFeature, &QAction::triggered, this, &QgsAttributeTableDialog::mActionAddFeature_triggered );
connect( mActionExpressionSelect, &QAction::triggered, this, &QgsAttributeTableDialog::mActionExpressionSelect_triggered );
connect( mMainView, &QgsDualView::showContextMenuExternally, this, &QgsAttributeTableDialog::showContextMenu );

Q_FOREACH ( const QgsField &field, mLayer->fields() )
{
@@ -1042,6 +1043,21 @@ void QgsAttributeTableDialog::setFilterExpression( const QString &filterString,
}


void QgsAttributeTableDialog::deleteFeature( const QgsFeatureId fid )
{
QgsDebugMsg( QString( "Delete %1" ).arg( fid ) );
mLayer->deleteFeature( fid );
}

void QgsAttributeTableDialog::showContextMenu( QgsActionMenu *menu, const QgsFeatureId fid )
{
if ( mLayer->isEditable() )
{
QAction *qAction = menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionDeleteSelected.svg" ) ), tr( "Delete feature" ) );
connect( qAction, &QAction::triggered, this, [this, fid]() { deleteFeature( fid ); } );
}
}

//
// QgsAttributeTableDock
//
@@ -219,6 +219,7 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib
void updateFieldFromExpressionSelected();
void viewModeChanged( QgsAttributeForm::Mode mode );
void formFilterSet( const QString &filter, QgsAttributeForm::FilterType type );
void showContextMenu( QgsActionMenu *menu, const QgsFeatureId fid );

private:
QMenu *mMenuActions = nullptr;
@@ -236,6 +237,7 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib
QgsAttributeEditorContext mEditorContext;

void updateMultiEditButtonState();
void deleteFeature( const QgsFeatureId fid );

friend class TestQgsAttributeTable;
};
@@ -74,6 +74,7 @@ void QgsDualView::init( QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const Qg
mTableView->horizontalHeader()->setContextMenuPolicy( Qt::CustomContextMenu );
connect( mTableView->horizontalHeader(), &QHeaderView::customContextMenuRequested, this, &QgsDualView::showViewHeaderMenu );
connect( mTableView, &QgsAttributeTableView::columnResized, this, &QgsDualView::tableColumnResized );
connect( mFeatureList, &QgsFeatureListView::willShowContextMenu, this, &QgsDualView::widgetWillShowContextMenu );

initLayerCache( !( request.flags() & QgsFeatureRequest::NoGeometry ) || !request.filterRect().isNull() );
initModels( mapCanvas, request, loadFeatures );
@@ -401,7 +402,6 @@ void QgsDualView::insertRecentlyUsedDisplayExpression( const QString &expression
mLastDisplayExpressionAction = previewAction;
}


void QgsDualView::mFeatureList_aboutToChangeEditSelection( bool &ok )
{
if ( mLayer->isEditable() && !mAttributeForm->save() )
@@ -543,7 +543,6 @@ void QgsDualView::viewWillShowContextMenu( QMenu *menu, const QModelIndex &atInd
return;
}


QModelIndex sourceIndex = mFilterModel->mapToSource( atIndex );

QAction *copyContentAction = new QAction( tr( "Copy cell content" ), this );
@@ -608,6 +607,13 @@ void QgsDualView::viewWillShowContextMenu( QMenu *menu, const QModelIndex &atInd
#endif
}


void QgsDualView::widgetWillShowContextMenu( QgsActionMenu *menu, const QModelIndex &atIndex )
{
emit showContextMenuExternally( menu, mFilterModel->rowToId( atIndex ) );
}


void QgsDualView::showViewHeaderMenu( QPoint point )
{
int col = mTableView->columnAt( point.x() );
@@ -269,6 +269,13 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
*/
void formModeChanged( QgsAttributeForm::Mode mode );

/**
* Emitted when selecting context menu on the feature list to create the context menu individually
* \param menu context menu
* \param fid feature id of the selected feature
*/
void showContextMenuExternally( QgsActionMenu *menu, const QgsFeatureId fid );

protected:
void hideEvent( QHideEvent *event ) override;

@@ -289,6 +296,8 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas

void viewWillShowContextMenu( QMenu *menu, const QModelIndex &atIndex );

void widgetWillShowContextMenu( QgsActionMenu *menu, const QModelIndex &atIndex );

void showViewHeaderMenu( QPoint point );

void organizeColumns();
@@ -19,7 +19,6 @@
#include <QSet>
#include <QSettings>

#include "qgsactionmenu.h"
#include "qgsattributetabledelegate.h"
#include "qgsattributetablefiltermodel.h"
#include "qgsattributetablemodel.h"
@@ -302,6 +301,9 @@ void QgsFeatureListView::contextMenuEvent( QContextMenuEvent *event )
QgsFeature feature = mModel->data( index, QgsFeatureListModel::FeatureRole ).value<QgsFeature>();

QgsActionMenu *menu = new QgsActionMenu( mModel->layerCache()->layer(), feature, QStringLiteral( "Feature" ), this );

emit willShowContextMenu( menu, index );

menu->exec( event->globalPos() );
}
}
@@ -20,6 +20,7 @@
#include "qgis_sip.h"
#include "qgis.h"
#include <qdebug.h>
#include "qgsactionmenu.h"

#include "qgsfeature.h" // For QgsFeatureIds
#include "qgis_gui.h"
@@ -146,6 +147,13 @@ class GUI_EXPORT QgsFeatureListView : public QListView
//! \note not available in Python bindings
void aboutToChangeEditSelection( bool &ok ) SIP_SKIP;

/**
* Is emitted, when the context menu is created to add the specific actions to it
* \param menu is the already created context menu
* \param atIndex is the position of the current feature in the model
*/
void willShowContextMenu( QgsActionMenu *menu, const QModelIndex &atIndex );

public slots:

/**
@@ -191,6 +199,7 @@ class GUI_EXPORT QgsFeatureListView : public QListView
bool mEditSelectionDrag = false; // Is set to true when the user initiated a left button click over an edit button and still keeps pressing //!< TODO
int mRowAnchor = 0;
QItemSelectionModel::SelectionFlags mCtrlDragSelectionFlag;

};

#endif
@@ -138,11 +138,13 @@ QgsRelationEditorWidget::QgsRelationEditorWidget( QWidget *parent )
connect( mSaveEditsButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::saveEdits );
connect( mAddFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::addFeature );
connect( mDuplicateFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::duplicateFeature );
connect( mDeleteFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::deleteFeature );
connect( mDeleteFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::deleteSelectedFeatures );
connect( mLinkFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::linkFeature );
connect( mUnlinkFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::unlinkFeature );
connect( mUnlinkFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::unlinkSelectedFeatures );
connect( mFeatureSelectionMgr, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsRelationEditorWidget::updateButtons );

connect( mDualView, &QgsDualView::showContextMenuExternally, this, &QgsRelationEditorWidget::showContextMenu );

// Set initial state for add/remove etc. buttons
updateButtons();
}
@@ -447,27 +449,55 @@ void QgsRelationEditorWidget::duplicateFeature()
}
}

void QgsRelationEditorWidget::deleteFeature()
void QgsRelationEditorWidget::deleteFeature( const QgsFeatureId featureid )
{
QgsVectorLayer *layer = nullptr;
QgsFeatureIds featureids;

featureids << featureid;

deleteFeatures( featureids );

}

void QgsRelationEditorWidget::deleteSelectedFeatures( )
{
deleteFeatures( mFeatureSelectionMgr->selectedFeatureIds() );
}

void QgsRelationEditorWidget::deleteFeatures( const QgsFeatureIds &featureids )
{
QgsVectorLayer *layer = nullptr;
if ( mNmRelation.isValid() )
// So far we expect the database to take care of cleaning up the linking table or restricting
// TODO: add more options for the behavior here
layer = mNmRelation.referencedLayer();
else
layer = mRelation.referencingLayer();
QgsDebugMsg( QString( "Delete %1" ).arg( mFeatureSelectionMgr->selectedFeatureIds().size() ) );
layer->deleteFeatures( mFeatureSelectionMgr->selectedFeatureIds() );

QgsDebugMsg( QString( "Delete %1" ).arg( featureids.size() ) );
layer->deleteFeatures( featureids );
}


void QgsRelationEditorWidget::unlinkFeature( const QgsFeatureId featureid )
{
QgsFeatureIds featureids;

featureids << featureid;

unlinkFeatures( featureids );
}

void QgsRelationEditorWidget::unlinkSelectedFeatures( )
{
unlinkFeatures( mFeatureSelectionMgr->selectedFeatureIds() );
}

void QgsRelationEditorWidget::unlinkFeature()
void QgsRelationEditorWidget::unlinkFeatures( const QgsFeatureIds &featureids )
{
if ( mNmRelation.isValid() )
{
QgsFeatureIterator selectedIterator = mNmRelation.referencedLayer()->getFeatures(
QgsFeatureRequest()
.setFilterFids( mFeatureSelectionMgr->selectedFeatureIds() )
.setFilterFids( featureids )
.setSubsetOfAttributes( mNmRelation.referencedFields() ) );

QgsFeature f;
@@ -514,7 +544,7 @@ void QgsRelationEditorWidget::unlinkFeature()
keyFields.insert( idx, fld );
}

Q_FOREACH ( QgsFeatureId fid, mFeatureSelectionMgr->selectedFeatureIds() )
Q_FOREACH ( QgsFeatureId fid, featureids )
{
QMapIterator<int, QgsField> it( keyFields );
while ( it.hasNext() )
@@ -630,3 +660,17 @@ void QgsRelationEditorWidget::setShowLabel( bool showLabel )
else
setTitle( QString() );
}

void QgsRelationEditorWidget::showContextMenu( QgsActionMenu *menu, const QgsFeatureId fid )
{
if ( mRelation.referencingLayer()->isEditable() )
{
QAction *qAction = nullptr;

qAction = menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionDeleteSelected.svg" ) ), tr( "Delete feature" ) );
connect( qAction, &QAction::triggered, this, [this, fid]() { deleteFeature( fid ); } );

qAction = menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionUnlink.svg" ) ), tr( "Unlink feature" ) );
connect( qAction, &QAction::triggered, this, [this, fid]() { unlinkFeature( fid ); } );
}
}
@@ -148,11 +148,14 @@ class GUI_EXPORT QgsRelationEditorWidget : public QgsCollapsibleGroupBox
void addFeature();
void duplicateFeature();
void linkFeature();
void deleteFeature();
void unlinkFeature();
void deleteFeature( const QgsFeatureId featureid = QgsFeatureId() );
void deleteSelectedFeatures();
void unlinkFeature( const QgsFeatureId featureid = QgsFeatureId() );
void unlinkSelectedFeatures();
void saveEdits();
void toggleEditing( bool state );
void onCollapsedStateChanged( bool collapsed );
void showContextMenu( QgsActionMenu *menu, const QgsFeatureId fid );

private:
void updateUi();
@@ -179,6 +182,20 @@ class GUI_EXPORT QgsRelationEditorWidget : public QgsCollapsibleGroupBox

bool mShowLabel = true;
bool mVisible = false;

/**
* Deletes the features
* \param featureids features to delete
* \since QGIS 3.00
*/
void deleteFeatures( const QgsFeatureIds &featureids );

/**
* Unlinks the features
* \param featureids features to unlink
* \since QGIS 3.00
*/
void unlinkFeatures( const QgsFeatureIds &featureids );
};

#endif // QGSRELATIONEDITOR_H

0 comments on commit 8392d7f

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