Skip to content
Permalink
Browse files

Add QgsExpressionStoreDialog

  • Loading branch information
elpaso committed Dec 16, 2019
1 parent 2ab794b commit 09345b5130c5dd33cad26f34519ca2cae916bcad
@@ -0,0 +1,60 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgsexpressionstoredialog.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/




class QgsExpressionStoreDialog : QDialog
{
%Docstring
A generic dialog for editing expression text, label and help text.

.. versionadded:: 3.12
%End

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

QgsExpressionStoreDialog( const QString &label,
const QString &expression,
const QString &helpText,
const QStringList &existingLabels,
QWidget *parent = 0 );
%Docstring
Creates a QgsExpressionStoreDialog with given ``label``, ``expression`` and ``helpText``.

:param existingLabels: list of existing labels for unique label validation
:param parent: optional parent widget
%End

QString expression( );
%Docstring
Returns the expression text
%End

QString label();
%Docstring
Returns the label text
%End

QString helpText();
%Docstring
Returns the help text
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgsexpressionstoredialog.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -65,6 +65,7 @@
%Include auto_generated/qgsencodingfiledialog.sip
%Include auto_generated/qgserrordialog.sip
%Include auto_generated/qgsexpressionbuilderdialog.sip
%Include auto_generated/qgsexpressionstoredialog.sip
%Include auto_generated/qgsexpressionbuilderwidget.sip
%Include auto_generated/qgsexpressionhighlighter.sip
%Include auto_generated/qgsexpressionlineedit.sip
@@ -153,6 +153,7 @@ QgsFieldCalculator::QgsFieldCalculator( QgsVectorLayer *vl, QWidget *parent )
mOnlyUpdateSelectedCheckBox->setText( tr( "Only update %1 selected features" ).arg( vl->selectedFeatureCount() ) );

builder->loadRecent( QStringLiteral( "fieldcalc" ) );
builder->loadStored( QStringLiteral( "fieldcalc" ) );

mInfoIcon->setPixmap( style()->standardPixmap( QStyle::SP_MessageBoxInformation ) );

@@ -292,6 +292,7 @@ SET(QGIS_GUI_SRCS
qgsexpressionhighlighter.cpp
qgsexpressionlineedit.cpp
qgsexpressionselectiondialog.cpp
qgsexpressionstoredialog.cpp
qgsextentgroupbox.cpp
qgsexternalresourcewidget.cpp
qgsfeatureselectiondlg.cpp
@@ -487,6 +488,7 @@ SET(QGIS_GUI_HDRS
qgsencodingfiledialog.h
qgserrordialog.h
qgsexpressionbuilderdialog.h
qgsexpressionstoredialog.h
qgsexpressionbuilderwidget.h
qgsexpressionhighlighter.h
qgsexpressionlineedit.h
@@ -919,6 +921,7 @@ SET(QGIS_GUI_UI_HDRS
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgscredentialdialog.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsdetaileditemwidgetbase.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsexpressionbuilderdialogbase.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsexpressionstoredialogbase.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsexpressionbuilder.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsexpressionselectiondialogbase.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsfeaturefilterwidget.h
@@ -861,6 +861,7 @@ void QgsDualView::modifySort()
expressionBuilder->setLayer( mLayer );
expressionBuilder->loadFieldNames();
expressionBuilder->loadRecent( QStringLiteral( "generic" ) );
expressionBuilder->loadStored( QStringLiteral( "generic" ) );
expressionBuilder->setExpressionText( sortExpression().isEmpty() ? mLayer->displayExpression() : sortExpression() );

sortingGroupBox->layout()->addWidget( expressionBuilder );
@@ -33,6 +33,7 @@ QgsExpressionBuilderDialog::QgsExpressionBuilderDialog( QgsVectorLayer *layer, c
builder->setExpressionText( startText );
builder->loadFieldNames();
builder->loadRecent( mRecentKey );
builder->loadStored( mRecentKey );

connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsExpressionBuilderDialog::showHelp );
}
@@ -32,6 +32,7 @@
#include "qgsexpressioncontextutils.h"
#include "qgsfieldformatterregistry.h"
#include "qgsfieldformatter.h"
#include "qgsexpressionstoredialog.h"

#include <QMenu>
#include <QFile>
@@ -41,7 +42,7 @@
#include <QComboBox>
#include <QGraphicsOpacityEffect>
#include <QPropertyAnimation>

#include <QMessageBox>

QgsExpressionBuilderWidget::QgsExpressionBuilderWidget( QWidget *parent )
: QWidget( parent )
@@ -61,6 +62,8 @@ QgsExpressionBuilderWidget::QgsExpressionBuilderWidget( QWidget *parent )
connect( mValuesListView, &QListView::doubleClicked, this, &QgsExpressionBuilderWidget::mValuesListView_doubleClicked );
connect( btnSaveExpression, &QPushButton::pressed, this, &QgsExpressionBuilderWidget::storeCurrentExpression );
connect( btnRemoveExpression, &QPushButton::pressed, this, &QgsExpressionBuilderWidget::removeSelectedExpression );
connect( btnClearEditor, &QPushButton::pressed, txtExpressionString, &QgsCodeEditorExpression::clear );

txtHelpText->setOpenExternalLinks( true );

mValueGroupBox->hide();
@@ -74,6 +77,13 @@ QgsExpressionBuilderWidget::QgsExpressionBuilderWidget( QWidget *parent )
expressionTree->setSortingEnabled( true );
expressionTree->sortByColumn( 0, Qt::AscendingOrder );

expressionTree->setSelectionMode( QAbstractItemView::SelectionMode::SingleSelection );

// Set icons for tool buttons
btnSaveExpression->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionFileSave.svg" ) ) );
btnRemoveExpression->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionDeleteSelected.svg" ) ) );
btnClearEditor->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionFileNew.svg" ) ) );

expressionTree->setContextMenuPolicy( Qt::CustomContextMenu );
connect( this, &QgsExpressionBuilderWidget::expressionParsed, this, &QgsExpressionBuilderWidget::setExpressionState );
connect( expressionTree, &QWidget::customContextMenuRequested, this, &QgsExpressionBuilderWidget::showContextMenu );
@@ -250,6 +260,10 @@ void QgsExpressionBuilderWidget::currentChanged( const QModelIndex &index, const
// Show the help for the current item.
QString help = loadFunctionHelp( item );
txtHelpText->setText( help );

btnRemoveExpression->setEnabled( item->parent() &&
item->parent()->text() == mStoredGroupName );

}

void QgsExpressionBuilderWidget::btnRun_pressed()
@@ -594,12 +608,12 @@ void QgsExpressionBuilderWidget::loadRecent( const QString &collection )
void QgsExpressionBuilderWidget::loadStored( const QString &collection )
{
mRecentKey = collection;
const QString groupName = tr( "Stored (%1)" ).arg( collection );
mStoredGroupName = tr( "Stored (%1)" ).arg( collection );

// Cleanup
if ( mExpressionGroups.contains( groupName ) )
if ( mExpressionGroups.contains( mStoredGroupName ) )
{
QgsExpressionItem *node = mExpressionGroups.value( groupName );
QgsExpressionItem *node = mExpressionGroups.value( mStoredGroupName );
node->removeRows( 0, node->rowCount() );
}

@@ -610,12 +624,13 @@ void QgsExpressionBuilderWidget::loadStored( const QString &collection )
QString helpText;
QString expression;
int i = 0;
for ( const auto &label : settings.childGroups() )
mStoredLabels = settings.childGroups();
for ( const auto &label : qgis::as_const( mStoredLabels ) )
{
settings.beginGroup( label );
expression = settings.value( QStringLiteral( "expression" ) ).toString();
helpText = settings.value( QStringLiteral( "helpText" ) ).toString();
this->registerItem( groupName, label, expression, helpText, QgsExpressionItem::ExpressionNode, false, i++ );
this->registerItem( mStoredGroupName, label, expression, helpText, QgsExpressionItem::ExpressionNode, false, i++ );
settings.endGroup();
}
}
@@ -629,6 +644,14 @@ void QgsExpressionBuilderWidget::saveToStored( const QString &label, const QStri
settings.setValue( QStringLiteral( "expression" ), expression );
settings.setValue( QStringLiteral( "helpText" ), helpText );
this->loadStored( collection );
// Scroll
const QModelIndexList idxs { expressionTree->model()->match( expressionTree->model()->index( 0, 0 ),
Qt::DisplayRole, label, 1,
Qt::MatchFlag::MatchRecursive ) };
if ( ! idxs.isEmpty() )
{
expressionTree->scrollTo( idxs.first() );
}
}

void QgsExpressionBuilderWidget::removeFromStored( const QString &name, const QString &collection )
@@ -771,6 +794,9 @@ void QgsExpressionBuilderWidget::txtExpressionString_textChanged()
QString text = expressionText();
clearErrors();

btnClearEditor->setEnabled( ! txtExpressionString->text().isEmpty() );
btnSaveExpression->setEnabled( false );

// If the string is empty the expression will still "fail" although
// we don't show the user an error as it will be confusing.
if ( text.isEmpty() )
@@ -838,6 +864,7 @@ void QgsExpressionBuilderWidget::txtExpressionString_textChanged()
setParserError( false );
setEvalError( false );
createMarkers( exp.rootNode() );
btnSaveExpression->setEnabled( true );
}

}
@@ -1201,21 +1228,34 @@ void QgsExpressionBuilderWidget::autosave()
void QgsExpressionBuilderWidget::storeCurrentExpression()
{
const QString expression { this->expressionText() };
saveToStored( expression, expression, expression, mRecentKey );
QgsExpressionStoreDialog dlg { expression, expression, QString( ), mStoredLabels };
if ( dlg.exec() == QDialog::DialogCode::Accepted )
{
saveToStored( dlg.label(), dlg.expression(), dlg.helpText(), mRecentKey );
}
}

void QgsExpressionBuilderWidget::removeSelectedExpression()
{
QModelIndex idx { expressionTree->currentIndex() };

// Get the item
QModelIndex idx = mProxyModel->mapToSource( expressionTree->currentIndex() );
QgsExpressionItem *item = dynamic_cast<QgsExpressionItem *>( mModel->itemFromIndex( idx ) );
if ( !item )
return;

// Don't handle the double-click if we are on a header node.
if ( item->getItemType() == QgsExpressionItem::Header )
// Don't handle remove if we are on a header node or the parent
// is not the stored group
if ( item->getItemType() == QgsExpressionItem::Header ||
( item->parent() && item->parent()->text() != mStoredGroupName ) )
return;

removeFromStored( item->text(), mRecentKey );
if ( QMessageBox::Yes == QMessageBox::question( this, tr( "Remove Stored Expression" ),
tr( "Do you really want to remove stored expressions '%1'?" ).arg( item->text() ),
QMessageBox::Yes | QMessageBox::No ) )
{
removeFromStored( item->text(), mRecentKey );
}

}

@@ -1281,10 +1321,6 @@ QString QgsExpressionBuilderWidget::loadFunctionHelp( QgsExpressionItem *express
return "<head><style>" + helpStylesheet() + "</style></head><body>" + helpContents + "</body>";
}





QgsExpressionItemSearchProxy::QgsExpressionItemSearchProxy()
{
setFilterCaseSensitivity( Qt::CaseInsensitive );
@@ -497,6 +497,8 @@ class GUI_EXPORT QgsExpressionBuilderWidget : public QWidget, private Ui::QgsExp
QPointer< QgsProject > mProject;
bool mEvalError = true;
bool mParserError = true;
QString mStoredGroupName;
QStringList mStoredLabels;
};

// clazy:excludeall=qstring-allocations
@@ -59,6 +59,7 @@ QgsExpressionSelectionDialog::QgsExpressionSelectionDialog( QgsVectorLayer *laye
mExpressionBuilder->setExpressionText( startText );
mExpressionBuilder->loadFieldNames();
mExpressionBuilder->loadRecent( QStringLiteral( "Selection" ) );
mExpressionBuilder->loadStored( QStringLiteral( "Selection" ) );

QgsExpressionContext context( QgsExpressionContextUtils::globalProjectLayerScopes( mLayer ) );
mExpressionBuilder->setExpressionContext( context );
@@ -0,0 +1,33 @@
#include "qgsexpressionstoredialog.h"
#include <QPushButton>
#include <QStyle>

QgsExpressionStoreDialog::QgsExpressionStoreDialog( const QString &label, const QString &expression, const QString &helpText, const QStringList &existingLabels, QWidget *parent )
: QDialog( parent )
, mExistingLabels( existingLabels )
{
setupUi( this );
mExpression->setText( expression );
mHelpText->setText( helpText );
connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsExpressionStoreDialog::accept );
connect( buttonBox, &QDialogButtonBox::rejected, this, &QgsExpressionStoreDialog::reject );
mValidationError->hide();
mValidationError->setStyleSheet( QStringLiteral( "QLabel { color : red; }" ) );
QPushButton *saveBtn { buttonBox->button( QDialogButtonBox::StandardButton::Save ) };
saveBtn->setEnabled( false );
connect( mLabel, &QLineEdit::textChanged, this, [ = ]( const QString & text )
{
if ( mExistingLabels.contains( text ) )
{
mValidationError->show();
saveBtn->setEnabled( false );
}
else
{
mValidationError->hide();
saveBtn->setEnabled( true );
}
} );
mLabel->setText( label );
}

@@ -0,0 +1,51 @@
#ifndef QGSEXPRESSIONSTOREDIALOG_H
#define QGSEXPRESSIONSTOREDIALOG_H

#include "qgis_gui.h"
#include <QDialog>
#include "ui_qgsexpressionstoredialogbase.h"



/**
* \ingroup gui
* A generic dialog for editing expression text, label and help text.
* \since QGIS 3.12
*/
class GUI_EXPORT QgsExpressionStoreDialog : public QDialog, private Ui::QgsExpressionStoreDialogBase
{
public:

/**
* Creates a QgsExpressionStoreDialog with given \a label, \a expression and \a helpText.
* \param existingLabels list of existing labels for unique label validation
* \param parent optional parent widget
*/
QgsExpressionStoreDialog( const QString &label,
const QString &expression,
const QString &helpText,
const QStringList &existingLabels,
QWidget *parent = nullptr );

/**
* Returns the expression text
*/
QString expression( ) { return mExpression->text( ); }

/**
* Returns the label text
*/
QString label() { return mLabel->text(); }

/**
* Returns the help text
*/
QString helpText() { return mHelpText->toHtml(); }

private:

QStringList mExistingLabels;

};

#endif // QGSEXPRESSIONSTOREDIALOG_H

0 comments on commit 09345b5

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