mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-08 00:05:32 -04:00
705 lines
20 KiB
C++
705 lines
20 KiB
C++
/***************************************************************************
|
|
qgssqlcomposerdialog.cpp
|
|
Dialog to compose SQL queries
|
|
|
|
begin : Apr 2016
|
|
copyright : (C) 2016 Even Rouault
|
|
email : even.rouault at spatialys.com
|
|
|
|
Adapted/ported from DBManager dlg_query_builder
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* 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 "qgssqlcomposerdialog.h"
|
|
#include "qgssqlstatement.h"
|
|
|
|
#include <QMessageBox>
|
|
|
|
#include <Qsci/qscilexer.h>
|
|
|
|
QgsSQLComposerDialog::TableSelectedCallback::~TableSelectedCallback()
|
|
{
|
|
}
|
|
|
|
QgsSQLComposerDialog::SQLValidatorCallback::~SQLValidatorCallback()
|
|
{
|
|
}
|
|
|
|
QgsSQLComposerDialog::QgsSQLComposerDialog( QWidget * parent, Qt::WindowFlags fl )
|
|
: QDialog( parent, fl )
|
|
, mTableSelectedCallback( nullptr )
|
|
, mSQLValidatorCallback( nullptr )
|
|
, mFocusedObject( nullptr )
|
|
, mAlreadyModifyingFields( false )
|
|
, mDistinct( false )
|
|
{
|
|
setupUi( this );
|
|
|
|
mQueryEdit->setWrapMode( QsciScintilla::WrapWord );
|
|
mQueryEdit->installEventFilter( this );
|
|
mColumnsEditor->installEventFilter( this );
|
|
mTablesEditor->installEventFilter( this );
|
|
mTableJoins->installEventFilter( this );
|
|
mWhereEditor->installEventFilter( this );
|
|
mOrderEditor->installEventFilter( this );
|
|
|
|
connect( mButtonBox->button( QDialogButtonBox::Reset ), SIGNAL( clicked() ),
|
|
this, SLOT( reset() ) );
|
|
|
|
connect( mQueryEdit, SIGNAL( textChanged() ),
|
|
this, SLOT( splitSQLIntoFields() ) );
|
|
connect( mColumnsEditor, SIGNAL( textChanged() ),
|
|
this, SLOT( buildSQLFromFields() ) );
|
|
connect( mTablesEditor, SIGNAL( textChanged( const QString & ) ),
|
|
this, SLOT( buildSQLFromFields() ) );
|
|
connect( mWhereEditor, SIGNAL( textChanged() ),
|
|
this, SLOT( buildSQLFromFields() ) );
|
|
connect( mOrderEditor, SIGNAL( textChanged() ),
|
|
this, SLOT( buildSQLFromFields() ) );
|
|
connect( mTableJoins, SIGNAL( cellChanged( int, int ) ),
|
|
this, SLOT( buildSQLFromFields() ) );
|
|
|
|
QStringList baseList;
|
|
baseList << "SELECT";
|
|
baseList << "FROM";
|
|
baseList << "JOIN";
|
|
baseList << "ON";
|
|
baseList << "USING";
|
|
baseList << "WHERE";
|
|
baseList << "AND";
|
|
baseList << "OR";
|
|
baseList << "NOT";
|
|
baseList << "IS";
|
|
baseList << "NULL";
|
|
baseList << "LIKE";
|
|
baseList << "ORDER";
|
|
baseList << "BY";
|
|
addApis( baseList );
|
|
|
|
QStringList operatorsList;
|
|
operatorsList << "AND";
|
|
operatorsList << "OR";
|
|
operatorsList << "NOT";
|
|
operatorsList << "=";
|
|
operatorsList << "<";
|
|
operatorsList << "<=";
|
|
operatorsList << ">";
|
|
operatorsList << ">=";
|
|
operatorsList << "<>";
|
|
operatorsList << "IS";
|
|
operatorsList << "IS NOT";
|
|
operatorsList << "IN";
|
|
operatorsList << "LIKE";
|
|
operatorsList << "BETWEEN";
|
|
addOperators( operatorsList );
|
|
|
|
mAggregatesCombo->hide();
|
|
mFunctionsCombo->hide();
|
|
mSpatialPredicatesCombo->hide();
|
|
mStringFunctionsCombo->hide();
|
|
|
|
delete mPageColumnsValues;
|
|
mPageColumnsValues = nullptr;
|
|
|
|
mRemoveJoinButton->setEnabled( false );
|
|
|
|
mTableJoins->setRowCount( 0 );
|
|
mTableJoins->setItem( 0, 0, new QTableWidgetItem( "" ) );
|
|
mTableJoins->setItem( 0, 1, new QTableWidgetItem( "" ) );
|
|
}
|
|
|
|
QgsSQLComposerDialog::~QgsSQLComposerDialog()
|
|
{
|
|
// Besides avoid memory leaks, this is useful since QSciAPIs::prepare()
|
|
// starts a thread. If the dialog was killed before the thread had started,
|
|
// he could run against a dead widget. This can happen in unit tests.
|
|
delete mQueryEdit->lexer()->apis();
|
|
mQueryEdit->lexer()->setAPIs( nullptr );
|
|
}
|
|
|
|
bool QgsSQLComposerDialog::eventFilter( QObject *obj, QEvent *event )
|
|
{
|
|
if ( event->type() == QEvent::FocusIn )
|
|
mFocusedObject = obj;
|
|
|
|
return QObject::eventFilter( obj, event );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::setTableSelectedCallback( TableSelectedCallback* tableSelectedCallback )
|
|
{
|
|
mTableSelectedCallback = tableSelectedCallback;
|
|
}
|
|
|
|
void QgsSQLComposerDialog::setSQLValidatorCallback( SQLValidatorCallback* sqlValidatorCallback )
|
|
{
|
|
mSQLValidatorCallback = sqlValidatorCallback;
|
|
}
|
|
|
|
void QgsSQLComposerDialog::setSql( const QString& sql )
|
|
{
|
|
mResetSql = sql;
|
|
mQueryEdit->setText( sql );
|
|
}
|
|
|
|
QString QgsSQLComposerDialog::sql() const
|
|
{
|
|
return mQueryEdit->text();
|
|
}
|
|
|
|
void QgsSQLComposerDialog::accept()
|
|
{
|
|
if ( mSQLValidatorCallback )
|
|
{
|
|
QString errorMsg;
|
|
if ( !mSQLValidatorCallback->isValid( sql(), errorMsg ) )
|
|
{
|
|
if ( errorMsg.isEmpty() )
|
|
errorMsg = tr( "An error occurred during evaluation of the SQL statement" );
|
|
QMessageBox::critical( this, tr( "SQL error" ), errorMsg );
|
|
return;
|
|
}
|
|
}
|
|
QDialog::accept();
|
|
}
|
|
|
|
void QgsSQLComposerDialog::buildSQLFromFields()
|
|
{
|
|
if ( mAlreadyModifyingFields )
|
|
return;
|
|
mAlreadyModifyingFields = true;
|
|
QString sql( "SELECT " );
|
|
if ( mDistinct )
|
|
sql += "DISTINCT ";
|
|
sql += mColumnsEditor->toPlainText();
|
|
sql += " FROM ";
|
|
sql += mTablesEditor->text();
|
|
|
|
int rows = mTableJoins->rowCount();
|
|
for ( int i = 0;i < rows;i++ )
|
|
{
|
|
QTableWidgetItem * itemTable = mTableJoins->item( i, 0 );
|
|
QTableWidgetItem * itemOn = mTableJoins->item( i, 1 );
|
|
if ( itemTable && !itemTable->text().isEmpty() &&
|
|
itemOn && !itemOn->text().isEmpty() )
|
|
{
|
|
sql += " JOIN ";
|
|
sql += itemTable->text();
|
|
sql += " ON ";
|
|
sql += itemOn->text();
|
|
}
|
|
}
|
|
|
|
if ( !mWhereEditor->toPlainText().isEmpty() )
|
|
{
|
|
sql += " WHERE ";
|
|
sql += mWhereEditor->toPlainText();
|
|
}
|
|
if ( !mOrderEditor->toPlainText().isEmpty() )
|
|
{
|
|
sql += " ORDER BY ";
|
|
sql += mOrderEditor->toPlainText();
|
|
}
|
|
mQueryEdit->setText( sql );
|
|
|
|
mAlreadyModifyingFields = false;
|
|
}
|
|
|
|
void QgsSQLComposerDialog::splitSQLIntoFields()
|
|
{
|
|
if ( mAlreadyModifyingFields )
|
|
return;
|
|
QgsSQLStatement sql( mQueryEdit->text() );
|
|
if ( sql.hasParserError() )
|
|
return;
|
|
const QgsSQLStatement::NodeSelect* nodeSelect = dynamic_cast<const QgsSQLStatement::NodeSelect*>( sql.rootNode() );
|
|
if ( nodeSelect == nullptr )
|
|
return;
|
|
mDistinct = nodeSelect->distinct();
|
|
QList<QgsSQLStatement::NodeSelectedColumn*> columns = nodeSelect->columns();
|
|
QString columnText;
|
|
Q_FOREACH ( QgsSQLStatement::NodeSelectedColumn* column, columns )
|
|
{
|
|
if ( !columnText.isEmpty() )
|
|
columnText += ", ";
|
|
columnText += column->dump();
|
|
}
|
|
|
|
QList<QgsSQLStatement::NodeTableDef*> tables = nodeSelect->tables();
|
|
QString tablesText;
|
|
Q_FOREACH ( QgsSQLStatement::NodeTableDef* table, tables )
|
|
{
|
|
if ( !tablesText.isEmpty() )
|
|
tablesText += ", ";
|
|
loadTableColumns( QgsSQLStatement::quotedIdentifierIfNeeded( table->name() ) );
|
|
tablesText += table->dump();
|
|
}
|
|
|
|
QString whereText;
|
|
QgsSQLStatement::Node* where = nodeSelect->where();
|
|
if ( where != nullptr )
|
|
whereText = where->dump();
|
|
|
|
QString orderText;
|
|
QList<QgsSQLStatement::NodeColumnSorted*> orderColumns = nodeSelect->orderBy();
|
|
Q_FOREACH ( QgsSQLStatement::NodeColumnSorted* column, orderColumns )
|
|
{
|
|
if ( !orderText.isEmpty() )
|
|
orderText += ", ";
|
|
orderText += column->dump();
|
|
}
|
|
|
|
QList<QgsSQLStatement::NodeJoin*> joins = nodeSelect->joins();
|
|
|
|
mAlreadyModifyingFields = true;
|
|
mColumnsEditor->setPlainText( columnText );
|
|
mTablesEditor->setText( tablesText );
|
|
mWhereEditor->setPlainText( whereText );
|
|
mOrderEditor->setPlainText( orderText );
|
|
|
|
mTableJoins->setRowCount( joins.size() + 1 );
|
|
int iRow = 0;
|
|
Q_FOREACH ( QgsSQLStatement::NodeJoin* join, joins )
|
|
{
|
|
loadTableColumns( QgsSQLStatement::quotedIdentifierIfNeeded( join->tableDef()->name() ) );
|
|
mTableJoins->setItem( iRow, 0 , new QTableWidgetItem( join->tableDef()->dump() ) );
|
|
if ( join->onExpr() )
|
|
mTableJoins->setItem( iRow, 1 , new QTableWidgetItem( join->onExpr()->dump() ) );
|
|
else
|
|
mTableJoins->setItem( iRow, 1 , new QTableWidgetItem( "" ) );
|
|
iRow ++;
|
|
}
|
|
mTableJoins->setItem( iRow, 0, new QTableWidgetItem( "" ) );
|
|
mTableJoins->setItem( iRow, 1, new QTableWidgetItem( "" ) );
|
|
|
|
mAlreadyModifyingFields = false;
|
|
}
|
|
|
|
void QgsSQLComposerDialog::addTableNames( const QStringList& list )
|
|
{
|
|
Q_FOREACH ( const QString& name, list )
|
|
mapTableEntryTextToName[name] = name;
|
|
mTablesCombo->addItems( list );
|
|
addApis( list );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::addTableNames( const QList<PairNameTitle> & listNameTitle )
|
|
{
|
|
QStringList listCombo;
|
|
QStringList listApi;
|
|
Q_FOREACH ( const PairNameTitle& pair, listNameTitle )
|
|
{
|
|
listApi << pair.first;
|
|
QString entryText( pair.first );
|
|
if ( !pair.second.isEmpty() && pair.second != pair.first )
|
|
{
|
|
if ( pair.second.size() < 40 )
|
|
entryText += " (" + pair.second + ")";
|
|
else
|
|
entryText += " (" + pair.second.mid( 0, 20 ) + "..." + pair.second.mid( pair.second.size() - 20 ) + ")";
|
|
}
|
|
listCombo << entryText;
|
|
mapTableEntryTextToName[entryText] = pair.first;
|
|
}
|
|
mTablesCombo->addItems( listCombo );
|
|
addApis( listApi );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::addColumnNames( const QStringList& list, const QString& tableName )
|
|
{
|
|
QList<PairNameType> listPair;
|
|
Q_FOREACH ( const QString& name, list )
|
|
listPair << PairNameType( name, QString() );
|
|
addColumnNames( listPair, tableName );
|
|
}
|
|
|
|
static QString sanitizeType( QString type )
|
|
{
|
|
if ( type.startsWith( "xs:" ) )
|
|
return type.mid( 3 );
|
|
if ( type.startsWith( "xsd:" ) )
|
|
return type.mid( 4 );
|
|
if ( type == "gml:AbstractGeometryType" )
|
|
return "geometry";
|
|
return type;
|
|
}
|
|
|
|
void QgsSQLComposerDialog::addColumnNames( const QList<PairNameType>& list, const QString& tableName )
|
|
{
|
|
mAlreadySelectedTables.insert( tableName );
|
|
if ( mColumnsCombo->count() > 1 )
|
|
mColumnsCombo->insertSeparator( mColumnsCombo->count() );
|
|
|
|
QStringList listCombo;
|
|
QStringList listApi;
|
|
Q_FOREACH ( const PairNameType& pair, list )
|
|
{
|
|
listApi << pair.first;
|
|
QString entryText( pair.first );
|
|
if ( !pair.second.isEmpty() )
|
|
{
|
|
entryText += " (" + sanitizeType( pair.second ) + ")";
|
|
}
|
|
listCombo << entryText;
|
|
mapColumnEntryTextToName[entryText] = pair.first;
|
|
}
|
|
mColumnsCombo->addItems( listCombo );
|
|
|
|
addApis( listApi );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::addOperators( const QStringList& list )
|
|
{
|
|
mOperatorsCombo->addItems( list );
|
|
addApis( list );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::getFunctionList( const QList<Function>& list,
|
|
QStringList& listApi,
|
|
QStringList& listCombo,
|
|
QMap<QString, QString>& mapEntryTextToName )
|
|
{
|
|
Q_FOREACH ( const Function& f, list )
|
|
{
|
|
listApi << f.name;
|
|
QString entryText( f.name );
|
|
entryText += "(";
|
|
if ( f.argumentList.size() )
|
|
{
|
|
for ( int i = 0;i < f.argumentList.size();i++ )
|
|
{
|
|
if ( f.minArgs >= 0 && i >= f.minArgs ) entryText += "[";
|
|
if ( i > 0 ) entryText += ", ";
|
|
if ( f.argumentList[i].name == "number" && !f.argumentList[i].type.isEmpty() )
|
|
{
|
|
entryText += sanitizeType( f.argumentList[i].type );
|
|
}
|
|
else
|
|
{
|
|
entryText += f.argumentList[i].name;
|
|
QString sanitizedType( sanitizeType( f.argumentList[i].type ) );
|
|
if ( !f.argumentList[i].type.isEmpty() &&
|
|
f.argumentList[i].name != sanitizedType )
|
|
{
|
|
entryText += ": ";
|
|
entryText += sanitizedType;
|
|
}
|
|
}
|
|
if ( f.minArgs >= 0 && i >= f.minArgs ) entryText += "]";
|
|
}
|
|
}
|
|
else if ( f.minArgs >= 0 && f.maxArgs > f.minArgs )
|
|
{
|
|
entryText += tr( "%1 to %2 arguments" ).arg( f.minArgs ).arg( f.maxArgs );
|
|
}
|
|
else if ( f.minArgs == 0 && f.maxArgs == 0 )
|
|
{
|
|
}
|
|
else if ( f.minArgs > 0 && f.maxArgs == f.minArgs )
|
|
{
|
|
if ( f.minArgs == 1 )
|
|
entryText += tr( "1 argument" );
|
|
else
|
|
entryText += tr( "%1 arguments" ).arg( f.minArgs );
|
|
}
|
|
else if ( f.minArgs >= 0 && f.maxArgs < 0 )
|
|
{
|
|
if ( f.minArgs > 1 )
|
|
entryText += tr( "%1 arguments or more" ).arg( f.minArgs );
|
|
else if ( f.minArgs == 1 )
|
|
entryText += tr( "1 argument or more" );
|
|
else
|
|
entryText += tr( "0 argument or more" );
|
|
}
|
|
entryText += ")";
|
|
if ( !f.returnType.isEmpty() )
|
|
entryText += ": " + sanitizeType( f.returnType );
|
|
listCombo << entryText;
|
|
mapEntryTextToName[entryText] = f.name + "(";
|
|
}
|
|
}
|
|
|
|
void QgsSQLComposerDialog::addSpatialPredicates( const QStringList& list )
|
|
{
|
|
QList<Function> listFunction;
|
|
Q_FOREACH ( const QString& name, list )
|
|
{
|
|
Function f;
|
|
f.name = name;
|
|
listFunction << f;
|
|
}
|
|
addSpatialPredicates( listFunction );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::addSpatialPredicates( const QList<Function>& list )
|
|
{
|
|
QStringList listApi;
|
|
QStringList listCombo;
|
|
getFunctionList( list, listApi, listCombo, mapSpatialPredicateEntryTextToName );
|
|
mSpatialPredicatesCombo->addItems( listCombo );
|
|
mSpatialPredicatesCombo->show();
|
|
addApis( listApi );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::addFunctions( const QStringList& list )
|
|
{
|
|
QList<Function> listFunction;
|
|
Q_FOREACH ( const QString& name, list )
|
|
{
|
|
Function f;
|
|
f.name = name;
|
|
listFunction << f;
|
|
}
|
|
addFunctions( listFunction );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::addFunctions( const QList<Function>& list )
|
|
{
|
|
QStringList listApi;
|
|
QStringList listCombo;
|
|
getFunctionList( list, listApi, listCombo, mapFunctionEntryTextToName );
|
|
mFunctionsCombo->addItems( listCombo );
|
|
mFunctionsCombo->show();
|
|
addApis( listApi );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::loadTableColumns( const QString& table )
|
|
{
|
|
if ( mTableSelectedCallback )
|
|
{
|
|
if ( !mAlreadySelectedTables.contains( table ) )
|
|
{
|
|
mTableSelectedCallback->tableSelected( table );
|
|
mAlreadySelectedTables.insert( table );
|
|
}
|
|
}
|
|
}
|
|
|
|
static void resetCombo( QComboBox* combo )
|
|
{
|
|
// We do it in a defered way, otherwise Valgrind complains when using QTest
|
|
// since basically this call a recursive call to QComboBox::setCurrentIndex()
|
|
// which cause internal QComboBox logic to operate on a destroyed object
|
|
// However that isn't reproduce in live session. Anyway this hack is safe
|
|
// in all modes.
|
|
QMetaObject::invokeMethod( combo, "setCurrentIndex", Qt::QueuedConnection, Q_ARG( int, 0 ) );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::on_mTablesCombo_currentIndexChanged( int )
|
|
{
|
|
int index = mTablesCombo->currentIndex();
|
|
if ( index <= 0 )
|
|
return;
|
|
QObject* obj = mFocusedObject;
|
|
QString newText = mapTableEntryTextToName[mTablesCombo->currentText()];
|
|
loadTableColumns( newText );
|
|
if ( obj == mTablesEditor )
|
|
{
|
|
QString currentText = mTablesEditor->text();
|
|
if ( currentText.isEmpty() )
|
|
mTablesEditor->setText( newText );
|
|
else
|
|
mTablesEditor->setText( currentText + ", " + newText );
|
|
}
|
|
else if ( obj == mTableJoins )
|
|
{
|
|
if ( mTableJoins->selectedItems().size() == 1 )
|
|
{
|
|
mTableJoins->selectedItems().at( 0 )->setText( newText );
|
|
}
|
|
}
|
|
else if ( obj == mWhereEditor )
|
|
{
|
|
mWhereEditor->insertPlainText( newText );
|
|
}
|
|
else if ( obj == mOrderEditor )
|
|
{
|
|
mOrderEditor->insertPlainText( newText );
|
|
}
|
|
else if ( obj == mQueryEdit )
|
|
{
|
|
mQueryEdit->insertText( newText );
|
|
}
|
|
resetCombo( mTablesCombo );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::on_mColumnsCombo_currentIndexChanged( int )
|
|
{
|
|
int index = mColumnsCombo->currentIndex();
|
|
if ( index <= 0 )
|
|
return;
|
|
QObject* obj = mFocusedObject;
|
|
QString newText = mapColumnEntryTextToName[mColumnsCombo->currentText()];
|
|
if ( obj == mColumnsEditor )
|
|
{
|
|
QString currentText = mColumnsEditor->toPlainText();
|
|
if ( currentText.isEmpty() )
|
|
mColumnsEditor->insertPlainText( newText );
|
|
else
|
|
mColumnsEditor->insertPlainText( ",\n" + newText );
|
|
}
|
|
else if ( obj == mTableJoins )
|
|
{
|
|
if ( mTableJoins->selectedItems().size() == 1 &&
|
|
mTableJoins->selectedItems().at( 0 )->column() == 1 )
|
|
{
|
|
QString currentText( mTableJoins->selectedItems().at( 0 )->text() );
|
|
if ( !currentText.isEmpty() && !currentText.contains( "=" ) )
|
|
mTableJoins->selectedItems().at( 0 )->setText( currentText + " = " + newText );
|
|
else
|
|
mTableJoins->selectedItems().at( 0 )->setText( currentText + newText );
|
|
}
|
|
}
|
|
else if ( obj == mWhereEditor )
|
|
{
|
|
mWhereEditor->insertPlainText( newText );
|
|
}
|
|
else if ( obj == mOrderEditor )
|
|
{
|
|
mOrderEditor->insertPlainText( newText );
|
|
}
|
|
else if ( obj == mQueryEdit )
|
|
{
|
|
mQueryEdit->insertText( newText );
|
|
}
|
|
resetCombo( mColumnsCombo );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::on_mFunctionsCombo_currentIndexChanged( int )
|
|
{
|
|
functionCurrentIndexChanged( mFunctionsCombo, mapFunctionEntryTextToName );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::on_mSpatialPredicatesCombo_currentIndexChanged( int )
|
|
{
|
|
functionCurrentIndexChanged( mSpatialPredicatesCombo, mapSpatialPredicateEntryTextToName );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::functionCurrentIndexChanged( QComboBox* combo,
|
|
const QMap<QString, QString>& mapEntryTextToName )
|
|
{
|
|
int index = combo->currentIndex();
|
|
if ( index <= 0 )
|
|
return;
|
|
QObject* obj = mFocusedObject;
|
|
QString newText = mapEntryTextToName[combo->currentText()];
|
|
if ( obj == mColumnsEditor )
|
|
{
|
|
mColumnsEditor->insertPlainText( newText );
|
|
}
|
|
else if ( obj == mWhereEditor )
|
|
{
|
|
mWhereEditor->insertPlainText( newText );
|
|
}
|
|
else if ( obj == mQueryEdit )
|
|
{
|
|
mQueryEdit->insertText( newText );
|
|
}
|
|
resetCombo( combo );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::on_mOperatorsCombo_currentIndexChanged( int )
|
|
{
|
|
int index = mOperatorsCombo->currentIndex();
|
|
if ( index <= 0 )
|
|
return;
|
|
QObject* obj = mFocusedObject;
|
|
QString newText = mOperatorsCombo->currentText();
|
|
if ( obj == mColumnsEditor )
|
|
{
|
|
mColumnsEditor->insertPlainText( newText );
|
|
}
|
|
else if ( obj == mWhereEditor )
|
|
{
|
|
mWhereEditor->insertPlainText( newText );
|
|
}
|
|
else if ( obj == mTableJoins )
|
|
{
|
|
if ( mTableJoins->selectedItems().size() == 1 &&
|
|
mTableJoins->selectedItems().at( 0 )->column() == 1 )
|
|
{
|
|
QString currentText( mTableJoins->selectedItems().at( 0 )->text() );
|
|
mTableJoins->selectedItems().at( 0 )->setText( currentText + newText );
|
|
}
|
|
}
|
|
else if ( obj == mQueryEdit )
|
|
{
|
|
mQueryEdit->insertText( newText );
|
|
}
|
|
resetCombo( mOperatorsCombo );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::on_mAddJoinButton_clicked()
|
|
{
|
|
int insertRow = mTableJoins->currentRow();
|
|
int rowCount = mTableJoins->rowCount();
|
|
if ( insertRow < 0 )
|
|
insertRow = rowCount;
|
|
mTableJoins->setRowCount( rowCount + 1 );
|
|
for ( int row = rowCount ; row > insertRow + 1; row -- )
|
|
{
|
|
mTableJoins->setItem( row, 0, mTableJoins->takeItem( row - 1, 0 ) );
|
|
mTableJoins->setItem( row, 1, mTableJoins->takeItem( row - 1, 1 ) );
|
|
}
|
|
mTableJoins->setItem(( insertRow == rowCount ) ? insertRow : insertRow + 1, 0, new QTableWidgetItem( "" ) );
|
|
mTableJoins->setItem(( insertRow == rowCount ) ? insertRow : insertRow + 1, 1, new QTableWidgetItem( "" ) );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::on_mRemoveJoinButton_clicked()
|
|
{
|
|
int row = mTableJoins->currentRow();
|
|
if ( row < 0 )
|
|
return;
|
|
int rowCount = mTableJoins->rowCount();
|
|
for ( ; row < rowCount - 1; row ++ )
|
|
{
|
|
mTableJoins->setItem( row, 0, mTableJoins->takeItem( row + 1, 0 ) );
|
|
mTableJoins->setItem( row, 1, mTableJoins->takeItem( row + 1, 1 ) );
|
|
}
|
|
mTableJoins->setRowCount( rowCount - 1 );
|
|
|
|
buildSQLFromFields();
|
|
}
|
|
|
|
void QgsSQLComposerDialog::reset()
|
|
{
|
|
mQueryEdit->setText( mResetSql );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::on_mTableJoins_itemSelectionChanged()
|
|
{
|
|
mRemoveJoinButton->setEnabled( mTableJoins->selectedItems().size() == 1 );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::addApis( const QStringList& list )
|
|
{
|
|
mApiList += list;
|
|
|
|
delete mQueryEdit->lexer()->apis();
|
|
QsciAPIs* apis = new QsciAPIs( mQueryEdit->lexer() );
|
|
|
|
Q_FOREACH ( const QString& str, mApiList )
|
|
{
|
|
apis->add( str );
|
|
}
|
|
|
|
apis->prepare();
|
|
mQueryEdit->lexer()->setAPIs( apis );
|
|
}
|
|
|
|
void QgsSQLComposerDialog::setSupportMultipleTables( bool on )
|
|
{
|
|
mJoinsLabels->setVisible( on );
|
|
mTableJoins->setVisible( on );
|
|
mAddJoinButton->setVisible( on );
|
|
mRemoveJoinButton->setVisible( on );
|
|
mTablesCombo->setVisible( on );
|
|
}
|