QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
qgsorderbydialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgosorderbydialog.cpp
3 
4  ---------------------
5  begin : 20.12.2015
6  copyright : (C) 2015 by Matthias Kuhn
7  email : [email protected]
8  ***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
17 #include "qgsorderbydialog.h"
18 
21 
22 #include <QTableWidget>
23 #include <QKeyEvent>
24 
26  : QDialog( parent )
27  , mLayer( layer )
28 {
29  setupUi( this );
30 
31  mOrderByTableWidget->horizontalHeader()->setResizeMode( QHeaderView::Stretch );
32  mOrderByTableWidget->horizontalHeader()->setResizeMode( 1, QHeaderView::ResizeToContents );
33  mOrderByTableWidget->horizontalHeader()->setResizeMode( 2, QHeaderView::ResizeToContents );
34 
35  mOrderByTableWidget->installEventFilter( this );
36 }
37 
39 {
40  mOrderByTableWidget->setRowCount( orderBy.length() + 1 );
41 
42  int i = 0;
43  Q_FOREACH ( const QgsFeatureRequest::OrderByClause& orderByClause, orderBy )
44  {
45  setRow( i, orderByClause );
46 
47  ++i;
48  }
49 
50  // Add an empty widget at the end
51  setRow( i, QgsFeatureRequest::OrderByClause( "" ) );
52 }
53 
55 {
57 
58  for ( int i = 0; i < mOrderByTableWidget->rowCount(); ++i )
59  {
60  QString expressionText = static_cast<QgsFieldExpressionWidget*>( mOrderByTableWidget->cellWidget( i, 0 ) )->currentText();
61  bool isExpression = static_cast<QgsFieldExpressionWidget*>( mOrderByTableWidget->cellWidget( i, 0 ) )->isExpression();
62 
63  if ( ! expressionText.isEmpty() )
64  {
65  bool asc = true;
66  int ascIndex = static_cast<QComboBox*>( mOrderByTableWidget->cellWidget( i, 1 ) )->currentIndex();
67  if ( ascIndex == 1 )
68  asc = false;
69 
70  bool nullsFirst = false;
71  int nullsFirstIndex = static_cast<QComboBox*>( mOrderByTableWidget->cellWidget( i, 2 ) )->currentIndex();
72  if ( nullsFirstIndex == 1 )
73  nullsFirst = true;
74 
75  if ( !isExpression )
76  expressionText = QgsExpression::quotedColumnRef( expressionText );
77 
78  QgsFeatureRequest::OrderByClause orderByClause( expressionText, asc, nullsFirst );
79 
80  orderBy << orderByClause;
81  }
82  }
83 
84  return orderBy;
85 }
86 
87 void QgsOrderByDialog::onExpressionChanged( const QString& expression )
88 {
89  // The sender() is the field widget which is the cell widget of the first column
90  int row;
91  for ( row = 0; row < mOrderByTableWidget->rowCount(); ++row )
92  {
93  if ( mOrderByTableWidget->cellWidget( row, 0 ) == sender() )
94  {
95  break;
96  }
97  }
98 
99  if ( expression.isEmpty() && row != mOrderByTableWidget->rowCount() - 1 )
100  {
101  mOrderByTableWidget->removeRow( row );
102  }
103  else if ( !expression.isEmpty() && row == mOrderByTableWidget->rowCount() - 1 )
104  {
105  mOrderByTableWidget->insertRow( mOrderByTableWidget->rowCount() );
106  setRow( row + 1, QgsFeatureRequest::OrderByClause( "" ) );
107  }
108 }
109 
110 void QgsOrderByDialog::setRow( int row, const QgsFeatureRequest::OrderByClause& orderByClause )
111 {
112  QgsFieldExpressionWidget* fieldExpression = new QgsFieldExpressionWidget();
113  fieldExpression->setLayer( mLayer );
114  fieldExpression->setField( orderByClause.expression().expression() );
115  connect( fieldExpression, SIGNAL( fieldChanged( QString ) ), this, SLOT( onExpressionChanged( QString ) ) );
116 
117  QComboBox* ascComboBox = new QComboBox();
118  ascComboBox->addItem( tr( "Ascending" ) );
119  ascComboBox->addItem( tr( "Descending" ) );
120  ascComboBox->setCurrentIndex( orderByClause.ascending() ? 0 : 1 );
121 
122  QComboBox* nullsFirstComboBox = new QComboBox();
123  nullsFirstComboBox->addItem( tr( "NULLs last" ) );
124  nullsFirstComboBox->addItem( tr( "NULLs first" ) );
125  nullsFirstComboBox->setCurrentIndex( orderByClause.nullsFirst() ? 1 : 0 );
126 
127  mOrderByTableWidget->setCellWidget( row, 0, fieldExpression );
128  mOrderByTableWidget->setCellWidget( row, 1, ascComboBox );
129  mOrderByTableWidget->setCellWidget( row, 2, nullsFirstComboBox );
130 }
131 
133 {
134  Q_UNUSED( obj )
135  Q_ASSERT( obj == mOrderByTableWidget );
136 
137  if ( e->type() == QEvent::KeyPress )
138  {
139  QKeyEvent* keyEvent = static_cast<QKeyEvent*>( e );
140 
141  if ( keyEvent->key() == Qt::Key_Delete )
142  {
143  if ( mOrderByTableWidget->currentRow() != mOrderByTableWidget->rowCount() - 1 )
144  mOrderByTableWidget->removeRow( mOrderByTableWidget->currentRow() );
145  return true;
146  }
147  }
148 
149  return false;
150 }
151 
The QgsFieldExpressionWidget class reates a widget to choose fields and edit expressions It contains ...
bool nullsFirst() const
Set if NULLS should be returned first.
Type type() const
void setupUi(QWidget *widget)
bool eventFilter(QObject *obj, QEvent *e) override
void setOrderBy(const QgsFeatureRequest::OrderBy &orderBy)
Set the order by to manage.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
bool ascending() const
Order ascending.
int length() const
QObject * sender() const
void setLayer(QgsVectorLayer *layer)
set the layer used to display the fields and expression
QString tr(const char *sourceText, const char *disambiguation, int n)
void addItem(const QString &text, const QVariant &userData)
bool isEmpty() const
int key() const
QString expression() const
Return the original, unmodified expression string.
The OrderByClause class represents an order by clause for a QgsFeatureRequest.
QgsExpression expression() const
The expression.
void setField(const QString &fieldName)
sets the current field or expression in the widget
void setCurrentIndex(int index)
QgsOrderByDialog(QgsVectorLayer *layer, QWidget *parent=nullptr)
Create a new order by dialog.
QgsFeatureRequest::OrderBy orderBy()
Get the order by defined in the dialog.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Represents a vector layer which manages a vector based data sets.
Represents a list of OrderByClauses, with the most important first and the least important last...