QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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 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)
void setLayer(QgsMapLayer *layer)
Sets the layer used to display the fields and expression.
bool ascending() const
Order ascending.
QgsExpression expression() const
The expression.
bool nullsFirst() const
Set if NULLS should be returned first.
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.
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:35
QString expression() const
Returns the original, unmodified expression string.
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...