2 changes: 1 addition & 1 deletion src/app/qgslabelinggui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ void QgsLabelingGui::showExpressionDialog()
dlg.setWindowTitle( tr( "Expression based label" ) );
if ( dlg.exec() == QDialog::Accepted )
{
QString expression = dlg.expressionBuilder()->getExpressionString();
QString expression = dlg.getExpressionText();
//Only add the expression if the user has entered some text.
if ( !expression.isEmpty() )
{
Expand Down
3 changes: 3 additions & 0 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ qgsludialog.cpp
qgssearchquerybuilder.cpp
qgsexpressionbuilderwidget.cpp
qgsexpressionbuilderdialog.cpp
qgsexpressionhighlighter.cpp
qgsquerybuilder.cpp
)

Expand Down Expand Up @@ -135,6 +136,7 @@ qgsprojectbadlayerguihandler.h
qgslonglongvalidator.h
qgssearchquerybuilder.h
qgsexpressionbuilderwidget.h
qgsexpressionhighlighter.h
qgsquerybuilder.h
)

Expand Down Expand Up @@ -170,6 +172,7 @@ qgsattributeeditor.h
qgsfieldvalidator.h
qgsexpressionbuilderwidget.h
qgsexpressionbuilderdialog.h
qgsexpressionhighlighter.h

attributetable/qgsattributetablemodel.h
attributetable/qgsattributetablememorymodel.h
Expand Down
5 changes: 5 additions & 0 deletions src/gui/qgsexpressionbuilderdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ void QgsExpressionBuilderDialog::setExpressionText( QString text )
builder->setExpressionString( text );
}

QString QgsExpressionBuilderDialog::getExpressionText()
{
return builder->getExpressionString();
}

void QgsExpressionBuilderDialog::closeEvent( QCloseEvent *event )
{
QDialog::closeEvent( event );
Expand Down
5 changes: 5 additions & 0 deletions src/gui/qgsexpressionbuilderdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
#include <QDialog>
#include "ui_qgsexpressionbuilderdialogbase.h"

/** A generic dialog for building expression strings
* @remarks This class also shows an example on how to use QgsExpressionBuilderWidget
*/
class GUI_EXPORT QgsExpressionBuilderDialog : public QDialog, private Ui::QgsExpressionBuilderDialogBase
{
public:
Expand All @@ -29,6 +32,8 @@ class GUI_EXPORT QgsExpressionBuilderDialog : public QDialog, private Ui::QgsExp

void setExpressionText( QString text );

QString getExpressionText();

protected:
/**
* Handle closing of the window
Expand Down
152 changes: 79 additions & 73 deletions src/gui/qgsexpressionbuilderwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ QgsExpressionBuilderWidget::QgsExpressionBuilderWidget( QWidget *parent )
// The open and save button are for future.
btnOpen->hide();
btnSave->hide();
highlighter = new QgsExpressionHighlighter( txtExpressionString->document() );

mModel = new QStandardItemModel( );
mProxyModel = new QgsExpressionItemSearchProxy();
Expand All @@ -41,15 +42,11 @@ QgsExpressionBuilderWidget::QgsExpressionBuilderWidget( QWidget *parent )

expressionTree->setContextMenuPolicy( Qt::CustomContextMenu );
connect( expressionTree, SIGNAL( customContextMenuRequested( const QPoint & ) ), this, SLOT( showContextMenu( const QPoint & ) ) );
connect( btnPlusPushButton, SIGNAL( pressed() ), this, SLOT( operatorButtonClicked() ) );
connect( btnMinusPushButton, SIGNAL( pressed() ), this, SLOT( operatorButtonClicked() ) );
connect( btnDividePushButton, SIGNAL( pressed() ), this, SLOT( operatorButtonClicked() ) );
connect( btnMultiplyPushButton, SIGNAL( pressed() ), this, SLOT( operatorButtonClicked() ) );
connect( btnExpButton, SIGNAL( pressed() ), this, SLOT( operatorButtonClicked() ) );
connect( btnConcatButton, SIGNAL( pressed() ), this, SLOT( operatorButtonClicked() ) );
connect( btnOpenBracketPushButton, SIGNAL( pressed() ), this, SLOT( operatorButtonClicked() ) );
connect( btnCloseBracketPushButton, SIGNAL( pressed() ), this, SLOT( operatorButtonClicked() ) );

foreach (QPushButton* button, this->mOperatorsGroupBox->findChildren<QPushButton *>())
{
connect( button, SIGNAL( pressed() ), this, SLOT( operatorButtonClicked() ) );
}

// TODO Can we move this stuff to QgsExpression, like the functions?
registerItem( tr( "Operators" ), "+", " + " );
Expand Down Expand Up @@ -152,12 +149,22 @@ void QgsExpressionBuilderWidget::loadFieldNames()
return;

const QgsFieldMap fieldMap = mLayer->pendingFields();
QgsFieldMap::const_iterator fieldIt = fieldMap.constBegin();
for ( ; fieldIt != fieldMap.constEnd(); ++fieldIt )
loadFieldNames( fieldMap );
}

void QgsExpressionBuilderWidget::loadFieldNames( QgsFieldMap fields )
{
if ( fields.isEmpty() )
return;

QStringList fieldNames;
foreach( QgsField field, fields )
{
QString fieldName = fieldIt.value().name();
registerItem( tr( "Fields" ), fieldName, " " + fieldName + " ", "", QgsExpressionItem::Field );
QString fieldName = field.name();
fieldNames << fieldName;
registerItem( tr( "Fields" ), fieldName, " \"" + fieldName + "\" ", "", QgsExpressionItem::Field );
}
highlighter->addFields( fieldNames );
}

void QgsExpressionBuilderWidget::fillFieldValues( int fieldIndex, int countLimit )
Expand Down Expand Up @@ -357,72 +364,71 @@ void QgsExpressionBuilderWidget::loadAllValues()

QString QgsExpressionBuilderWidget::loadFunctionHelp( QgsExpressionItem* functionName )
{
if ( functionName != NULL )
if ( functionName == NULL )
return "";

// set up the path to the help file
QString helpFilesPath = QgsApplication::pkgDataPath() + "/resources/function_help/";
/*
* determine the locale and create the file name from
* the context id
*/
QString lang = QLocale::system().name();

QSettings settings;
if ( settings.value( "locale/overrideFlag", false ).toBool() )
{
// set up the path to the help file
QString helpFilesPath = QgsApplication::pkgDataPath() + "/resources/function_help/";
/*
* determine the locale and create the file name from
* the context id
*/
QString lang = QLocale::system().name();

QSettings settings;
if ( settings.value( "locale/overrideFlag", false ).toBool() )
{
QLocale l( settings.value( "locale/userLocale", "en_US" ).toString() );
lang = l.name();
}
/*
* If the language isn't set on the system, assume en_US,
* otherwise we get the banner at the top of the help file
* saying it isn't available in "your" language. Some systems
* may be installed without the LANG environment being set.
*/
if ( lang.length() == 0 || lang == "C" )
{
lang = "en_US";
}
QString fullHelpPath = helpFilesPath + functionName->text() + "-" + lang;
// get the help content and title from the localized file
QString helpContents;
QFile file( fullHelpPath );
// check to see if the localized version exists
if ( !file.exists() )
{
// change the file name to the en_US version (default)
fullHelpPath = helpFilesPath + functionName->text() + "-en_US";
file.setFileName( fullHelpPath );

// Check for some sort of english locale and if not found, include
// translate this for us message
if ( !lang.contains( "en_" ) )
{
helpContents = "<i>" + tr( "This help file is not available in your language %1. If you would like to translate it, please contact the QGIS development team." ).arg( lang ) + "</i><hr />";
}
QLocale l( settings.value( "locale/userLocale", "en_US" ).toString() );
lang = l.name();
}
/*
* If the language isn't set on the system, assume en_US,
* otherwise we get the banner at the top of the help file
* saying it isn't available in "your" language. Some systems
* may be installed without the LANG environment being set.
*/
if ( lang.length() == 0 || lang == "C" )
{
lang = "en_US";
}
QString fullHelpPath = helpFilesPath + functionName->text() + "-" + lang;
// get the help content and title from the localized file
QString helpContents;
QFile file( fullHelpPath );
// check to see if the localized version exists
if ( !file.exists() )
{
// change the file name to the en_US version (default)
fullHelpPath = helpFilesPath + functionName->text() + "-en_US";
file.setFileName( fullHelpPath );

}
if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
// Check for some sort of english locale and if not found, include
// translate this for us message
if ( !lang.contains( "en_" ) )
{
helpContents = tr( "This help file does not exist for your language:<p><b>%1</b><p>If you would like to create it, contact the QGIS development team" )
.arg( fullHelpPath );
helpContents = "<i>" + tr( "This help file is not available in your language %1. If you would like to translate it, please contact the QGIS development team." ).arg( lang ) + "</i><hr />";
}
else

}
if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
{
helpContents = tr( "This help file does not exist for your language:<p><b>%1</b><p>If you would like to create it, contact the QGIS development team" )
.arg( fullHelpPath );
}
else
{
QTextStream in( &file );
in.setCodec( "UTF-8" ); // Help files must be in Utf-8
while ( !in.atEnd() )
{
QTextStream in( &file );
in.setCodec( "UTF-8" ); // Help files must be in Utf-8
while ( !in.atEnd() )
{
QString line = in.readLine();
helpContents += line;
}
QString line = in.readLine();
helpContents += line;
}
file.close();

// Set the browser text to the help contents
QString myStyle = QgsApplication::reportStyleSheet();
helpContents = "<head><style>" + myStyle + "</style></head><body>" + helpContents + "</body>";
return helpContents;
}
return "";
file.close();

// Set the browser text to the help contents
QString myStyle = QgsApplication::reportStyleSheet();
helpContents = "<head><style>" + myStyle + "</style></head><body>" + helpContents + "</body>";
return helpContents;
}
5 changes: 5 additions & 0 deletions src/gui/qgsexpressionbuilderwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <QWidget>
#include "ui_qgsexpressionbuilder.h"
#include "qgsvectorlayer.h"
#include "qgsexpressionhighlighter.h"

#include "QStandardItemModel"
#include "QStandardItem"
Expand Down Expand Up @@ -119,6 +120,8 @@ class GUI_EXPORT QgsExpressionBuilderWidget : public QWidget, private Ui::QgsExp
*/
void loadFieldNames();

void loadFieldNames( QgsFieldMap fields );

/** Gets the expression string that has been set in the expression area.
* @returns The expression as a string. */
QString getExpressionString();
Expand All @@ -137,6 +140,7 @@ class GUI_EXPORT QgsExpressionBuilderWidget : public QWidget, private Ui::QgsExp
QString helpText = "",
QgsExpressionItem::ItemType type = QgsExpressionItem::ExpressionNode );


public slots:
void on_expressionTree_clicked( const QModelIndex &index );
void on_expressionTree_doubleClicked( const QModelIndex &index );
Expand Down Expand Up @@ -166,6 +170,7 @@ class GUI_EXPORT QgsExpressionBuilderWidget : public QWidget, private Ui::QgsExp
QgsExpressionItemSearchProxy *mProxyModel;
QMap<QString, QgsExpressionItem*> mExpressionGroups;
QgsFeature mFeature;
QgsExpressionHighlighter* highlighter;
};

#endif // QGSEXPRESSIONBUILDER_H
60 changes: 60 additions & 0 deletions src/gui/qgsexpressionhighlighter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/***************************************************************************
qgsexpressionhighlighter.cpp - A syntax highlighter for a qgsexpression
--------------------------------------
Date : 28-Dec-2011
Copyright : (C) 2011 by Nathan Woodrow
Email : woodrow.nathan at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsexpressionhighlighter.h"

QgsExpressionHighlighter::QgsExpressionHighlighter( QTextDocument *parent)
: QSyntaxHighlighter( parent )
{
HighlightingRule rule;

quotationFormat.setForeground( Qt::darkGreen );
rule.pattern = QRegExp( "\'.*\'" );
rule.format = quotationFormat;
highlightingRules.append( rule );

columnNameFormat.setForeground( Qt::darkRed );
rule.pattern = QRegExp( "\".*\"" );
rule.format = columnNameFormat;
highlightingRules.append( rule );
}

void QgsExpressionHighlighter::addFields(QStringList fieldList)
{
columnNameFormat.setForeground( Qt::darkRed );
HighlightingRule rule;
foreach (const QString field, fieldList)
{
rule.pattern = QRegExp("\\b" + field + "\\b");
rule.format = columnNameFormat;
highlightingRules.append( rule );
}
}

void QgsExpressionHighlighter::highlightBlock( const QString &text )
{
foreach( const HighlightingRule &rule, highlightingRules )
{
QRegExp expression( rule.pattern );
int index = expression.indexIn( text );
while ( index >= 0 )
{
int length = expression.matchedLength();
setFormat( index, length, rule.format );
index = expression.indexIn( text, index + length );
}
}
}

53 changes: 53 additions & 0 deletions src/gui/qgsexpressionhighlighter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/***************************************************************************
qgsexpressionhighlighter.h - A syntax highlighter for a qgsexpression
--------------------------------------
Date : 28-Dec-2011
Copyright : (C) 2011 by Nathan Woodrow
Email : woodrow.nathan at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSEXPRESSIONHIGHLIGHTER_H
#define QGSEXPRESSIONHIGHLIGHTER_H

#include "qgsfield.h"
#include <QSyntaxHighlighter>

#include <QHash>
#include <QTextCharFormat>
#include <QStringList>

class QTextDocument;

class QgsExpressionHighlighter : QSyntaxHighlighter
{
Q_OBJECT

public:
QgsExpressionHighlighter( QTextDocument *parent = 0 );
void addFields( QStringList fieldList );

protected:
void highlightBlock( const QString &text );

private:
struct HighlightingRule
{
QRegExp pattern;
QTextCharFormat format;
};
QVector<HighlightingRule> highlightingRules;

QTextCharFormat columnNameFormat;
QTextCharFormat keywordFormat;
QTextCharFormat quotationFormat;
QTextCharFormat functionFormat;
};

#endif // QGSEXPRESSIONHIGHLIGHTER_H
Loading