mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-06 00:07:29 -04:00
Merge pull request #5137 from m-kuhn/expressionhistory
[FEATURE] History for attribute table form view display expressions
This commit is contained in:
commit
f0cf4c3ee8
@ -13,6 +13,8 @@
|
||||
# #
|
||||
###########################################################################
|
||||
|
||||
set -e
|
||||
|
||||
export PYTHONPATH=${HOME}/osgeo4travis/lib/python3.3/site-packages/
|
||||
export PATH=${HOME}/osgeo4travis/bin:${HOME}/osgeo4travis/sbin:${HOME}/OTB-5.6.0-Linux64/bin:${PATH}
|
||||
export LD_LIBRARY_PATH=${HOME}/osgeo4travis/lib
|
||||
@ -27,18 +29,17 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
export OTB_APPLICATION_PATH=${HOME}/OTB-5.6.0-Linux64/lib/otb/applications
|
||||
export LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so
|
||||
|
||||
export CTEST_BUILD_COMMAND="/usr/bin/make -j3 -i -k"
|
||||
export CTEST_BUILD_COMMAND="/usr/bin/make -j3 -i"
|
||||
|
||||
# This works around an issue where travis would timeout on master because
|
||||
# This works around an issue where travis would timeout because
|
||||
# when make is run inside ctest no output is generated. At the current time
|
||||
# nobody know why, but at least this workaround gets travis results for master
|
||||
# nobody know why, but at least this workaround gets travis results
|
||||
# back. Better approaches VERY welcome.
|
||||
if [[ ${TRAVIS_PULL_REQUEST} == "false" ]];
|
||||
then
|
||||
pushd build
|
||||
$CTEST_BUILD_COMMAND
|
||||
popd
|
||||
fi
|
||||
pushd build
|
||||
echo "travis_fold:start:qgis_build"
|
||||
$CTEST_BUILD_COMMAND
|
||||
echo "travis_fold:end:qgis_build"
|
||||
popd
|
||||
|
||||
python ${TRAVIS_BUILD_DIR}/.ci/travis/scripts/ctest2travis.py \
|
||||
xvfb-run ctest -V -E "$(cat ${DIR}/blacklist.txt | sed -r '/^(#.*?)?$/d' | paste -sd '|' -)" -S ${DIR}/../travis.ctest --output-on-failure
|
||||
|
@ -171,13 +171,6 @@ class QgsDualView : QStackedWidget
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
||||
void columnBoxInit();
|
||||
%Docstring
|
||||
Initializes widgets which depend on the attributes of this layer
|
||||
%End
|
||||
|
||||
public slots:
|
||||
|
||||
void setCurrentEditSelection( const QgsFeatureIds &fids );
|
||||
@ -244,6 +237,9 @@ class QgsDualView : QStackedWidget
|
||||
\param mode new mode
|
||||
%End
|
||||
|
||||
protected:
|
||||
virtual void hideEvent( QHideEvent *event );
|
||||
|
||||
};
|
||||
|
||||
class QgsAttributeTableAction : QAction
|
||||
|
@ -56,7 +56,6 @@ QgsDualView::QgsDualView( QWidget *parent )
|
||||
|
||||
mConditionalFormatWidget->hide();
|
||||
|
||||
mPreviewActionMapper = new QSignalMapper( this );
|
||||
|
||||
mPreviewColumnsMenu = new QMenu( this );
|
||||
mActionPreviewColumnsMenu->setMenu( mPreviewColumnsMenu );
|
||||
@ -66,7 +65,6 @@ QgsDualView::QgsDualView( QWidget *parent )
|
||||
|
||||
// Connect layer list preview signals
|
||||
connect( mActionExpressionPreview, &QAction::triggered, this, &QgsDualView::previewExpressionBuilder );
|
||||
connect( mPreviewActionMapper, static_cast < void ( QSignalMapper::* )( QObject * ) > ( &QSignalMapper::mapped ), this, &QgsDualView::previewColumnChanged );
|
||||
connect( mFeatureList, &QgsFeatureListView::displayExpressionChanged, this, &QgsDualView::previewExpressionChanged );
|
||||
}
|
||||
|
||||
@ -149,16 +147,15 @@ void QgsDualView::columnBoxInit()
|
||||
if ( fieldIndex == -1 )
|
||||
continue;
|
||||
|
||||
if ( QgsGui::editorWidgetRegistry()->findBest( mLayer, field.name() ).type() != QLatin1String( "Hidden" ) )
|
||||
QString fieldName = field.name();
|
||||
if ( QgsGui::editorWidgetRegistry()->findBest( mLayer, fieldName ).type() != QLatin1String( "Hidden" ) )
|
||||
{
|
||||
QIcon icon = mLayer->fields().iconForField( fieldIndex );
|
||||
QString text = field.name();
|
||||
QString text = mLayer->attributeDisplayName( fieldIndex );
|
||||
|
||||
// Generate action for the preview popup button of the feature list
|
||||
QAction *previewAction = new QAction( icon, text, mFeatureListPreviewButton );
|
||||
mPreviewActionMapper->setMapping( previewAction, previewAction );
|
||||
connect( previewAction, &QAction::triggered, this, [previewAction, this]( bool ) { this->mPreviewActionMapper->map( previewAction ); }
|
||||
);
|
||||
connect( previewAction, &QAction::triggered, this, [ = ] { previewColumnChanged( previewAction, fieldName ); } );
|
||||
mPreviewColumnsMenu->addAction( previewAction );
|
||||
|
||||
if ( text == defaultField )
|
||||
@ -168,21 +165,26 @@ void QgsDualView::columnBoxInit()
|
||||
}
|
||||
}
|
||||
|
||||
QAction *sortByPreviewExpression = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "sort.svg" ) ), tr( "Sort by preview expression" ), this );
|
||||
connect( sortByPreviewExpression, &QAction::triggered, this, &QgsDualView::sortByPreviewExpression );
|
||||
mFeatureListPreviewButton->addAction( sortByPreviewExpression );
|
||||
|
||||
QAction *separator = new QAction( mFeatureListPreviewButton );
|
||||
separator->setSeparator( true );
|
||||
mFeatureListPreviewButton->addAction( separator );
|
||||
restoreRecentDisplayExpressions();
|
||||
|
||||
// If there is no single field found as preview
|
||||
if ( !mFeatureListPreviewButton->defaultAction() )
|
||||
{
|
||||
mFeatureList->setDisplayExpression( displayExpression );
|
||||
mFeatureListPreviewButton->setDefaultAction( mActionExpressionPreview );
|
||||
mDisplayExpression = mFeatureList->displayExpression();
|
||||
setDisplayExpression( mFeatureList->displayExpression() );
|
||||
}
|
||||
else
|
||||
{
|
||||
mFeatureListPreviewButton->defaultAction()->trigger();
|
||||
}
|
||||
|
||||
QAction *sortByPreviewExpression = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "sort.svg" ) ), tr( "Sort by preview expression" ), this );
|
||||
connect( sortByPreviewExpression, &QAction::triggered, this, &QgsDualView::sortByPreviewExpression );
|
||||
mFeatureListPreviewButton->addAction( sortByPreviewExpression );
|
||||
}
|
||||
|
||||
void QgsDualView::setView( QgsDualView::ViewMode view )
|
||||
@ -314,6 +316,95 @@ void QgsDualView::initModels( QgsMapCanvas *mapCanvas, const QgsFeatureRequest &
|
||||
mFeatureListModel = new QgsFeatureListModel( mFilterModel, mFilterModel );
|
||||
}
|
||||
|
||||
void QgsDualView::restoreRecentDisplayExpressions()
|
||||
{
|
||||
const QVariantList previewExpressions = mLayer->customProperty( QStringLiteral( "dualview/previewExpressions" ) ).toList();
|
||||
|
||||
for ( const QVariant &previewExpression : previewExpressions )
|
||||
insertRecentlyUsedDisplayExpression( previewExpression.toString() );
|
||||
}
|
||||
|
||||
void QgsDualView::saveRecentDisplayExpressions() const
|
||||
{
|
||||
QList<QAction *> actions = mFeatureListPreviewButton->actions();
|
||||
|
||||
// Remove existing same action
|
||||
int index = actions.indexOf( mLastDisplayExpressionAction );
|
||||
if ( index != -1 )
|
||||
{
|
||||
QVariantList previewExpressions;
|
||||
for ( ; index < actions.length(); ++index )
|
||||
{
|
||||
QAction *action = actions.at( index );
|
||||
previewExpressions << action->property( "previewExpression" );
|
||||
}
|
||||
|
||||
mLayer->setCustomProperty( QStringLiteral( "dualview/previewExpressions" ), previewExpressions );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsDualView::setDisplayExpression( const QString &expression )
|
||||
{
|
||||
mDisplayExpression = expression;
|
||||
insertRecentlyUsedDisplayExpression( expression );
|
||||
}
|
||||
|
||||
void QgsDualView::insertRecentlyUsedDisplayExpression( const QString &expression )
|
||||
{
|
||||
QList<QAction *> actions = mFeatureListPreviewButton->actions();
|
||||
|
||||
// Remove existing same action
|
||||
int index = actions.indexOf( mLastDisplayExpressionAction );
|
||||
if ( index != -1 )
|
||||
{
|
||||
for ( int i = 0; index + i < actions.length(); ++i )
|
||||
{
|
||||
QAction *action = actions.at( index );
|
||||
if ( action->text() == expression || i >= 9 )
|
||||
{
|
||||
if ( action == mLastDisplayExpressionAction )
|
||||
mLastDisplayExpressionAction = nullptr;
|
||||
mFeatureListPreviewButton->removeAction( action );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !mLastDisplayExpressionAction )
|
||||
mLastDisplayExpressionAction = action;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString name = expression;
|
||||
QIcon icon = QgsApplication::getThemeIcon( QStringLiteral( "/mIconExpressionPreview.svg" ) );
|
||||
if ( expression.startsWith( QLatin1String( "COALESCE( \"" ) ) && expression.endsWith( QLatin1String( ", '<NULL>' )" ) ) )
|
||||
{
|
||||
name = expression.mid( 11, expression.length() - 24 ); // Numbers calculated from the COALESCE / <NULL> parts
|
||||
|
||||
int fieldIndex = mLayer->fields().indexOf( name );
|
||||
if ( fieldIndex != -1 )
|
||||
{
|
||||
name = mLayer->attributeDisplayName( fieldIndex );
|
||||
icon = mLayer->fields().iconForField( fieldIndex );
|
||||
}
|
||||
else
|
||||
{
|
||||
name = expression;
|
||||
}
|
||||
}
|
||||
|
||||
QAction *previewAction = new QAction( icon, name, mFeatureListPreviewButton );
|
||||
previewAction->setProperty( "previewExpression", expression );
|
||||
connect( previewAction, &QAction::triggered, this, [expression, this]( bool )
|
||||
{
|
||||
setDisplayExpression( expression );
|
||||
mFeatureListPreviewButton->setText( expression );
|
||||
}
|
||||
);
|
||||
|
||||
mFeatureListPreviewButton->insertAction( mLastDisplayExpressionAction, previewAction );
|
||||
mLastDisplayExpressionAction = previewAction;
|
||||
}
|
||||
|
||||
void QgsDualView::on_mFeatureList_aboutToChangeEditSelection( bool &ok )
|
||||
{
|
||||
if ( mLayer->isEditable() && !mAttributeForm->save() )
|
||||
@ -387,33 +478,27 @@ void QgsDualView::previewExpressionBuilder()
|
||||
mFeatureListPreviewButton->setPopupMode( QToolButton::MenuButtonPopup );
|
||||
}
|
||||
|
||||
mDisplayExpression = mFeatureList->displayExpression();
|
||||
setDisplayExpression( mFeatureList->displayExpression() );
|
||||
}
|
||||
|
||||
void QgsDualView::previewColumnChanged( QObject *action )
|
||||
void QgsDualView::previewColumnChanged( QAction *previewAction, const QString &expression )
|
||||
{
|
||||
QAction *previewAction = qobject_cast< QAction * >( action );
|
||||
|
||||
if ( previewAction )
|
||||
if ( !mFeatureList->setDisplayExpression( QStringLiteral( "COALESCE( \"%1\", '<NULL>' )" ).arg( expression ) ) )
|
||||
{
|
||||
if ( !mFeatureList->setDisplayExpression( QStringLiteral( "COALESCE( \"%1\", '<NULL>' )" ).arg( previewAction->text() ) ) )
|
||||
{
|
||||
QMessageBox::warning( this,
|
||||
tr( "Could not set preview column" ),
|
||||
tr( "Could not set column '%1' as preview column.\nParser error:\n%2" )
|
||||
.arg( previewAction->text(), mFeatureList->parserErrorString() )
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
mFeatureListPreviewButton->setDefaultAction( previewAction );
|
||||
mFeatureListPreviewButton->setPopupMode( QToolButton::InstantPopup );
|
||||
}
|
||||
QMessageBox::warning( this,
|
||||
tr( "Could not set preview column" ),
|
||||
tr( "Could not set column '%1' as preview column.\nParser error:\n%2" )
|
||||
.arg( previewAction->text(), mFeatureList->parserErrorString() )
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
mFeatureListPreviewButton->setText( previewAction->text() );
|
||||
mFeatureListPreviewButton->setIcon( previewAction->icon() );
|
||||
mFeatureListPreviewButton->setPopupMode( QToolButton::InstantPopup );
|
||||
}
|
||||
|
||||
mDisplayExpression = mFeatureList->displayExpression();
|
||||
|
||||
Q_ASSERT( previewAction );
|
||||
setDisplayExpression( mFeatureList->displayExpression() );
|
||||
}
|
||||
|
||||
int QgsDualView::featureCount()
|
||||
@ -438,6 +523,12 @@ void QgsDualView::copyCellContent() const
|
||||
}
|
||||
}
|
||||
|
||||
void QgsDualView::hideEvent( QHideEvent *event )
|
||||
{
|
||||
Q_UNUSED( event )
|
||||
saveRecentDisplayExpressions();
|
||||
}
|
||||
|
||||
void QgsDualView::viewWillShowContextMenu( QMenu *menu, const QModelIndex &atIndex )
|
||||
{
|
||||
if ( !menu )
|
||||
|
@ -197,13 +197,6 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
|
||||
*/
|
||||
QString sortExpression() const;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Initializes widgets which depend on the attributes of this layer
|
||||
*/
|
||||
void columnBoxInit();
|
||||
|
||||
public slots:
|
||||
|
||||
/**
|
||||
@ -265,6 +258,9 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
|
||||
*/
|
||||
void formModeChanged( QgsAttributeForm::Mode mode );
|
||||
|
||||
protected:
|
||||
virtual void hideEvent( QHideEvent *event ) override;
|
||||
|
||||
private slots:
|
||||
|
||||
void on_mFeatureList_aboutToChangeEditSelection( bool &ok );
|
||||
@ -278,7 +274,7 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
|
||||
|
||||
void previewExpressionBuilder();
|
||||
|
||||
void previewColumnChanged( QObject *previewAction );
|
||||
void previewColumnChanged( QAction *previewAction, const QString &expression );
|
||||
|
||||
void viewWillShowContextMenu( QMenu *menu, const QModelIndex &atIndex );
|
||||
|
||||
@ -335,16 +331,26 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
|
||||
void rebuildFullLayerCache();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Initializes widgets which depend on the attributes of this layer
|
||||
*/
|
||||
void columnBoxInit();
|
||||
void initLayerCache( bool cacheGeometry );
|
||||
void initModels( QgsMapCanvas *mapCanvas, const QgsFeatureRequest &request, bool loadFeatures );
|
||||
void restoreRecentDisplayExpressions();
|
||||
void saveRecentDisplayExpressions() const;
|
||||
void setDisplayExpression( const QString &expression );
|
||||
void insertRecentlyUsedDisplayExpression( const QString &expression );
|
||||
|
||||
QgsAttributeEditorContext mEditorContext;
|
||||
QgsAttributeTableModel *mMasterModel = nullptr;
|
||||
QgsAttributeTableFilterModel *mFilterModel = nullptr;
|
||||
QgsFeatureListModel *mFeatureListModel = nullptr;
|
||||
QgsAttributeForm *mAttributeForm = nullptr;
|
||||
QSignalMapper *mPreviewActionMapper = nullptr;
|
||||
QMenu *mPreviewColumnsMenu = nullptr;
|
||||
QMenu *mPreviewActionMenu = nullptr;
|
||||
QAction *mLastDisplayExpressionAction = nullptr;
|
||||
QMenu *mHorizontalHeaderMenu = nullptr;
|
||||
QgsVectorLayerCache *mLayerCache = nullptr;
|
||||
QgsVectorLayer *mLayer = nullptr;
|
||||
|
Loading…
x
Reference in New Issue
Block a user