QGIS API Documentation  3.6.0-Noosa (5873452)
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 #include "qgsvectorlayer.h"
22 
23 #include <QTableWidget>
24 #include <QKeyEvent>
25 
27  : QDialog( parent )
28  , mLayer( layer )
29 {
30  setupUi( this );
31 
32  mOrderByTableWidget->horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch );
33  mOrderByTableWidget->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::ResizeToContents );
34  mOrderByTableWidget->horizontalHeader()->setSectionResizeMode( 2, QHeaderView::ResizeToContents );
35 
36  mOrderByTableWidget->installEventFilter( this );
37 
38  connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsOrderByDialog::showHelp );
39 }
40 
42 {
43  mOrderByTableWidget->setRowCount( orderBy.length() + 1 );
44 
45  int i = 0;
46  Q_FOREACH ( const QgsFeatureRequest::OrderByClause &orderByClause, orderBy )
47  {
48  setRow( i, orderByClause );
49 
50  ++i;
51  }
52 
53  // Add an empty widget at the end
54  setRow( i, QgsFeatureRequest::OrderByClause( QString() ) );
55 }
56 
58 {
60 
61  for ( int i = 0; i < mOrderByTableWidget->rowCount(); ++i )
62  {
63  QString expressionText = static_cast<QgsFieldExpressionWidget *>( mOrderByTableWidget->cellWidget( i, 0 ) )->currentText();
64  bool isExpression = static_cast<QgsFieldExpressionWidget *>( mOrderByTableWidget->cellWidget( i, 0 ) )->isExpression();
65 
66  if ( ! expressionText.isEmpty() )
67  {
68  bool asc = true;
69  int ascIndex = static_cast<QComboBox *>( mOrderByTableWidget->cellWidget( i, 1 ) )->currentIndex();
70  if ( ascIndex == 1 )
71  asc = false;
72 
73  bool nullsFirst = false;
74  int nullsFirstIndex = static_cast<QComboBox *>( mOrderByTableWidget->cellWidget( i, 2 ) )->currentIndex();
75  if ( nullsFirstIndex == 1 )
76  nullsFirst = true;
77 
78  if ( !isExpression )
79  expressionText = QgsExpression::quotedColumnRef( expressionText );
80 
81  QgsFeatureRequest::OrderByClause orderByClause( expressionText, asc, nullsFirst );
82 
83  orderBy << orderByClause;
84  }
85  }
86 
87  return orderBy;
88 }
89 
90 void QgsOrderByDialog::onExpressionChanged( const QString &expression )
91 {
92  // The sender() is the field widget which is the cell widget of the first column
93  int row;
94  for ( row = 0; row < mOrderByTableWidget->rowCount(); ++row )
95  {
96  if ( mOrderByTableWidget->cellWidget( row, 0 ) == sender() )
97  {
98  break;
99  }
100  }
101 
102  if ( expression.isEmpty() && row != mOrderByTableWidget->rowCount() - 1 )
103  {
104  mOrderByTableWidget->removeRow( row );
105  }
106  else if ( !expression.isEmpty() && row == mOrderByTableWidget->rowCount() - 1 )
107  {
108  mOrderByTableWidget->insertRow( mOrderByTableWidget->rowCount() );
109  setRow( row + 1, QgsFeatureRequest::OrderByClause( QString() ) );
110  }
111 }
112 
113 void QgsOrderByDialog::setRow( int row, const QgsFeatureRequest::OrderByClause &orderByClause )
114 {
115  QgsFieldExpressionWidget *fieldExpression = new QgsFieldExpressionWidget();
116  fieldExpression->setLayer( mLayer );
117  fieldExpression->setField( orderByClause.expression().expression() );
118  connect( fieldExpression, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) >( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsOrderByDialog::onExpressionChanged );
119 
120  QComboBox *ascComboBox = new QComboBox();
121  ascComboBox->addItem( tr( "Ascending" ) );
122  ascComboBox->addItem( tr( "Descending" ) );
123  ascComboBox->setCurrentIndex( orderByClause.ascending() ? 0 : 1 );
124 
125  QComboBox *nullsFirstComboBox = new QComboBox();
126  nullsFirstComboBox->addItem( tr( "NULLs last" ) );
127  nullsFirstComboBox->addItem( tr( "NULLs first" ) );
128  nullsFirstComboBox->setCurrentIndex( orderByClause.nullsFirst() ? 1 : 0 );
129 
130  mOrderByTableWidget->setCellWidget( row, 0, fieldExpression );
131  mOrderByTableWidget->setCellWidget( row, 1, ascComboBox );
132  mOrderByTableWidget->setCellWidget( row, 2, nullsFirstComboBox );
133 }
134 
135 bool QgsOrderByDialog::eventFilter( QObject *obj, QEvent *e )
136 {
137  Q_UNUSED( obj )
138  Q_ASSERT( obj == mOrderByTableWidget );
139 
140  if ( e->type() == QEvent::KeyPress )
141  {
142  QKeyEvent *keyEvent = static_cast<QKeyEvent *>( e );
143 
144  if ( keyEvent->key() == Qt::Key_Delete )
145  {
146  if ( mOrderByTableWidget->currentRow() != mOrderByTableWidget->rowCount() - 1 )
147  mOrderByTableWidget->removeRow( mOrderByTableWidget->currentRow() );
148  return true;
149  }
150  }
151 
152  return QDialog::eventFilter( obj, e );
153 }
154 
155 void QgsOrderByDialog::showHelp()
156 {
157  QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html#layer-rendering" ) );
158 }
The QgsFieldExpressionWidget class reates a widget to choose fields and edit expressions It contains ...
bool nullsFirst() const
Set if NULLS should be returned first.
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.
void setLayer(QgsMapLayer *layer)
Sets the layer used to display the fields and expression.
QString expression() const
Returns the original, unmodified expression string.
void fieldChanged(const QString &fieldName)
the signal is emitted when the currently selected field changes
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
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
QgsOrderByDialog(QgsVectorLayer *layer, QWidget *parent=nullptr)
Create a new order by dialog.
QgsFeatureRequest::OrderBy orderBy()
Gets the order by defined in the dialog.
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...