QGIS API Documentation  2.14.0-Essen
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 
62  if ( ! expressionText.isEmpty() )
63  {
64  bool asc = true;
65  int ascIndex = static_cast<QComboBox*>( mOrderByTableWidget->cellWidget( i, 1 ) )->currentIndex();
66  if ( ascIndex == 1 )
67  asc = false;
68 
69  bool nullsFirst = false;
70  int nullsFirstIndex = static_cast<QComboBox*>( mOrderByTableWidget->cellWidget( i, 2 ) )->currentIndex();
71  if ( nullsFirstIndex == 1 )
72  nullsFirst = true;
73 
74  QgsFeatureRequest::OrderByClause orderByClause( expressionText, asc, nullsFirst );
75 
76  orderBy << orderByClause;
77  }
78  }
79 
80  return orderBy;
81 }
82 
83 void QgsOrderByDialog::onExpressionChanged( const QString& expression )
84 {
85  // The sender() is the field widget which is the cell widget of the first column
86  int row;
87  for ( row = 0; row < mOrderByTableWidget->rowCount(); ++row )
88  {
89  if ( mOrderByTableWidget->cellWidget( row, 0 ) == sender() )
90  {
91  break;
92  }
93  }
94 
95  if ( expression.isEmpty() && row != mOrderByTableWidget->rowCount() - 1 )
96  {
97  mOrderByTableWidget->removeRow( row );
98  }
99  else if ( !expression.isEmpty() && row == mOrderByTableWidget->rowCount() - 1 )
100  {
101  mOrderByTableWidget->insertRow( mOrderByTableWidget->rowCount() );
102  setRow( row + 1, QgsFeatureRequest::OrderByClause( "" ) );
103  }
104 }
105 
106 void QgsOrderByDialog::setRow( int row, const QgsFeatureRequest::OrderByClause& orderByClause )
107 {
108  QgsFieldExpressionWidget* fieldExpression = new QgsFieldExpressionWidget();
109  fieldExpression->setLayer( mLayer );
110  fieldExpression->setField( orderByClause.expression().expression() );
111  connect( fieldExpression, SIGNAL( fieldChanged( QString ) ), this, SLOT( onExpressionChanged( QString ) ) );
112 
113  QComboBox* ascComboBox = new QComboBox();
114  ascComboBox->addItem( tr( "Ascending" ) );
115  ascComboBox->addItem( tr( "Descending" ) );
116  ascComboBox->setCurrentIndex( orderByClause.ascending() ? 0 : 1 );
117 
118  QComboBox* nullsFirstComboBox = new QComboBox();
119  nullsFirstComboBox->addItem( tr( "NULLs last" ) );
120  nullsFirstComboBox->addItem( tr( "NULLs first" ) );
121  nullsFirstComboBox->setCurrentIndex( orderByClause.nullsFirst() ? 1 : 0 );
122 
123  mOrderByTableWidget->setCellWidget( row, 0, fieldExpression );
124  mOrderByTableWidget->setCellWidget( row, 1, ascComboBox );
125  mOrderByTableWidget->setCellWidget( row, 2, nullsFirstComboBox );
126 }
127 
129 {
130  Q_UNUSED( obj )
131  Q_ASSERT( obj == mOrderByTableWidget );
132 
133  if ( e->type() == QEvent::KeyPress )
134  {
135  QKeyEvent* keyEvent = static_cast<QKeyEvent*>( e );
136 
137  if ( keyEvent->key() == Qt::Key_Delete )
138  {
139  if ( mOrderByTableWidget->currentRow() != mOrderByTableWidget->rowCount() - 1 )
140  mOrderByTableWidget->removeRow( mOrderByTableWidget->currentRow() );
141  return true;
142  }
143  }
144 
145  return false;
146 }
147 
The QgsFieldExpressionWidget class reates a widget to choose fields and edit expressions It contains ...
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.
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)
bool ascending() const
Order ascending.
void addItem(const QString &text, const QVariant &userData)
QgsExpression expression() const
The expression.
bool isEmpty() const
bool nullsFirst() const
Set if NULLS should be returned first.
int key() const
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
void setCurrentIndex(int index)
QString expression() const
Return the original, unmodified expression string.
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...