mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
[FEATURE] Allow definition of rendering order for renderers
This allows defining the order in which features are processed by renderers.
This commit is contained in:
parent
a5f88181f6
commit
73ba0e805a
34
python/gui/qgsorderbydialog.sip
Normal file
34
python/gui/qgsorderbydialog.sip
Normal file
@ -0,0 +1,34 @@
|
||||
/***************************************************************************
|
||||
qgsorderbydialog.h
|
||||
|
||||
---------------------
|
||||
begin : 20.12.2015
|
||||
copyright : (C) 2015 by Matthias Kuhn
|
||||
email : matthias@opengis.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
class QgsOrderByDialog : QDialog
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include "qgsorderbydialog.h"
|
||||
%End
|
||||
public:
|
||||
QgsOrderByDialog( QgsVectorLayer* layer, QWidget* parent = nullptr );
|
||||
|
||||
/**
|
||||
* Set the order by to manage
|
||||
*/
|
||||
void setOrderBys( const QList<QgsFeatureRequest::OrderByClause>& orderBys );
|
||||
|
||||
/**
|
||||
* Get the order by defined in the dialog
|
||||
*/
|
||||
QgsFeatureRequest::OrderBy orderBys();
|
||||
};
|
@ -346,7 +346,7 @@ void QgsFeatureRequest::OrderBy::load( const QDomElement& elem )
|
||||
for ( int i = 0; i < clauses.size(); ++i )
|
||||
{
|
||||
QDomElement clauseElem = clauses.at( i ).toElement();
|
||||
QString expression = clauseElem.toText().data();
|
||||
QString expression = clauseElem.text();
|
||||
bool asc = clauseElem.attribute( "asc" ).toInt() != 0;
|
||||
bool nullsFirst = clauseElem.attribute( "nullsFirst" ).toInt() != 0;
|
||||
|
||||
|
@ -150,10 +150,13 @@ bool QgsVectorLayerRenderer::render()
|
||||
QgsRectangle requestExtent = mContext.extent();
|
||||
mRendererV2->modifyRequestExtent( requestExtent, mContext );
|
||||
|
||||
QgsFeatureRequest::OrderBy orderBy = mRendererV2->orderBy();
|
||||
|
||||
QgsFeatureRequest featureRequest = QgsFeatureRequest()
|
||||
.setFilterRect( requestExtent )
|
||||
.setSubsetOfAttributes( mAttrNames, mFields )
|
||||
.setExpressionContext( mContext.expressionContext() );
|
||||
.setExpressionContext( mContext.expressionContext() )
|
||||
.setOrderBys( orderBy );
|
||||
|
||||
const QgsFeatureFilterProvider* featureFilterProvider = mContext.featureFilterProvider();
|
||||
if ( featureFilterProvider )
|
||||
|
@ -498,7 +498,7 @@ QgsCategorizedSymbolRendererV2* QgsCategorizedSymbolRendererV2::clone() const
|
||||
r->setUsingSymbolLevels( usingSymbolLevels() );
|
||||
r->setSizeScaleField( sizeScaleField() );
|
||||
|
||||
copyPaintEffect( r );
|
||||
copyRendererData( r );
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -761,6 +761,13 @@ QDomElement QgsCategorizedSymbolRendererV2::save( QDomDocument& doc )
|
||||
if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
|
||||
mPaintEffect->saveProperties( doc, rendererElem );
|
||||
|
||||
if ( !mOrderBy.isEmpty() )
|
||||
{
|
||||
QDomElement orderBy = doc.createElement( "orderby" );
|
||||
mOrderBy.save( orderBy );
|
||||
rendererElem.appendChild( orderBy );
|
||||
}
|
||||
|
||||
return rendererElem;
|
||||
}
|
||||
|
||||
|
@ -529,7 +529,7 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::clone() const
|
||||
r->setSizeScaleField( sizeScaleField() );
|
||||
r->setLabelFormat( labelFormat() );
|
||||
r->setGraduatedMethod( graduatedMethod() );
|
||||
copyPaintEffect( r );
|
||||
copyRendererData( r );
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -1171,6 +1171,13 @@ QDomElement QgsGraduatedSymbolRendererV2::save( QDomDocument& doc )
|
||||
if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
|
||||
mPaintEffect->saveProperties( doc, rendererElem );
|
||||
|
||||
if ( !mOrderBy.isEmpty() )
|
||||
{
|
||||
QDomElement orderBy = doc.createElement( "orderby" );
|
||||
mOrderBy.save( orderBy );
|
||||
rendererElem.appendChild( orderBy );
|
||||
}
|
||||
|
||||
return rendererElem;
|
||||
}
|
||||
|
||||
|
@ -297,7 +297,7 @@ QgsHeatmapRenderer* QgsHeatmapRenderer::clone() const
|
||||
newRenderer->setMaximumValue( mExplicitMax );
|
||||
newRenderer->setRenderQuality( mRenderQuality );
|
||||
newRenderer->setWeightExpression( mWeightExpressionString );
|
||||
copyPaintEffect( newRenderer );
|
||||
copyRendererData( newRenderer );
|
||||
|
||||
return newRenderer;
|
||||
}
|
||||
@ -365,6 +365,13 @@ QDomElement QgsHeatmapRenderer::save( QDomDocument& doc )
|
||||
if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
|
||||
mPaintEffect->saveProperties( doc, rendererElem );
|
||||
|
||||
if ( !mOrderBy.isEmpty() )
|
||||
{
|
||||
QDomElement orderBy = doc.createElement( "orderby" );
|
||||
mOrderBy.save( orderBy );
|
||||
rendererElem.appendChild( orderBy );
|
||||
}
|
||||
|
||||
return rendererElem;
|
||||
}
|
||||
|
||||
|
@ -204,6 +204,15 @@ void QgsFeatureRendererV2::setScaleMethodToSymbol( QgsSymbolV2* symbol, int scal
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFeatureRendererV2::copyRendererData( QgsFeatureRendererV2* destRenderer ) const
|
||||
{
|
||||
if ( !destRenderer || !mPaintEffect )
|
||||
return;
|
||||
|
||||
destRenderer->setPaintEffect( mPaintEffect->clone() );
|
||||
destRenderer->mOrderBy = mOrderBy;
|
||||
}
|
||||
|
||||
void QgsFeatureRendererV2::copyPaintEffect( QgsFeatureRendererV2 *destRenderer ) const
|
||||
{
|
||||
if ( !destRenderer || !mPaintEffect )
|
||||
@ -212,7 +221,6 @@ void QgsFeatureRendererV2::copyPaintEffect( QgsFeatureRendererV2 *destRenderer )
|
||||
destRenderer->setPaintEffect( mPaintEffect->clone() );
|
||||
}
|
||||
|
||||
|
||||
QgsFeatureRendererV2::QgsFeatureRendererV2( const QString& type )
|
||||
: mType( type )
|
||||
, mUsingSymbolLevels( false )
|
||||
@ -331,6 +339,10 @@ QgsFeatureRendererV2* QgsFeatureRendererV2::load( QDomElement& element )
|
||||
{
|
||||
r->setPaintEffect( QgsPaintEffectRegistry::instance()->createEffect( effectElem ) );
|
||||
}
|
||||
|
||||
// restore order by
|
||||
QDomElement orderByElem = element.firstChildElement( "orderby" );
|
||||
r->mOrderBy.load( orderByElem );
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@ -344,6 +356,12 @@ QDomElement QgsFeatureRendererV2::save( QDomDocument& doc )
|
||||
if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
|
||||
mPaintEffect->saveProperties( doc, rendererElem );
|
||||
|
||||
if ( !mOrderBy.isEmpty() )
|
||||
{
|
||||
QDomElement orderBy = doc.createElement( "orderby" );
|
||||
mOrderBy.save( orderBy );
|
||||
rendererElem.appendChild( orderBy );
|
||||
}
|
||||
return rendererElem;
|
||||
}
|
||||
|
||||
@ -598,6 +616,16 @@ void QgsFeatureRendererV2::setPaintEffect( QgsPaintEffect *effect )
|
||||
mPaintEffect = effect;
|
||||
}
|
||||
|
||||
QgsFeatureRequest::OrderBy QgsFeatureRendererV2::orderBy()
|
||||
{
|
||||
return mOrderBy;
|
||||
}
|
||||
|
||||
void QgsFeatureRendererV2::setOrderBy( const QgsFeatureRequest::OrderBy& orderBys )
|
||||
{
|
||||
mOrderBy = orderBys;
|
||||
}
|
||||
|
||||
void QgsFeatureRendererV2::convertSymbolSizeScale( QgsSymbolV2 * symbol, QgsSymbolV2::ScaleMethod method, const QString & field )
|
||||
{
|
||||
if ( symbol->type() == QgsSymbolV2::Marker )
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "qgsrendercontext.h"
|
||||
#include "qgssymbolv2.h"
|
||||
#include "qgsfield.h"
|
||||
#include "qgsfeaturerequest.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
@ -343,6 +344,18 @@ class CORE_EXPORT QgsFeatureRendererV2
|
||||
*/
|
||||
void setForceRasterRender( bool forceRaster ) { mForceRaster = forceRaster; }
|
||||
|
||||
/**
|
||||
* Get the order in which features shall be processed by this renderer.
|
||||
* @note added in QGIS 2.14
|
||||
*/
|
||||
QgsFeatureRequest::OrderBy orderBy();
|
||||
|
||||
/**
|
||||
* Define the order in which features shall be processed by this renderer.
|
||||
* @note added in QGIS 2.14
|
||||
*/
|
||||
void setOrderBy( const QgsFeatureRequest::OrderBy& orderBys );
|
||||
|
||||
protected:
|
||||
QgsFeatureRendererV2( const QString& type );
|
||||
|
||||
@ -366,10 +379,21 @@ class CORE_EXPORT QgsFeatureRendererV2
|
||||
|
||||
void setScaleMethodToSymbol( QgsSymbolV2* symbol, int scaleMethod );
|
||||
|
||||
/** Copies paint effect of this renderer to another renderer
|
||||
/**
|
||||
* Clones generic renderer data to another renderer.
|
||||
* Currently clones
|
||||
* * Order By
|
||||
* * Paint Effect
|
||||
*
|
||||
* @param destRenderer destination renderer for copied effect
|
||||
*/
|
||||
void copyPaintEffect( QgsFeatureRendererV2 *destRenderer ) const;
|
||||
void copyRendererData( QgsFeatureRendererV2 *destRenderer ) const;
|
||||
|
||||
/** Copies paint effect of this renderer to another renderer
|
||||
* @param destRenderer destination renderer for copied effect
|
||||
* @deprecated use copyRendererData instead
|
||||
*/
|
||||
Q_DECL_DEPRECATED void copyPaintEffect( QgsFeatureRendererV2 *destRenderer ) const;
|
||||
|
||||
QString mType;
|
||||
|
||||
@ -393,6 +417,8 @@ class CORE_EXPORT QgsFeatureRendererV2
|
||||
*/
|
||||
static void convertSymbolRotation( QgsSymbolV2 * symbol, const QString & field );
|
||||
|
||||
QgsFeatureRequest::OrderBy mOrderBy;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY( QgsFeatureRendererV2 )
|
||||
};
|
||||
|
@ -201,7 +201,7 @@ QgsSingleSymbolRendererV2* QgsSingleSymbolRendererV2::clone() const
|
||||
QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( mSymbol->clone() );
|
||||
r->setUsingSymbolLevels( usingSymbolLevels() );
|
||||
r->setSizeScaleField( sizeScaleField() );
|
||||
copyPaintEffect( r );
|
||||
copyRendererData( r );
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -381,6 +381,12 @@ QDomElement QgsSingleSymbolRendererV2::save( QDomDocument& doc )
|
||||
if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
|
||||
mPaintEffect->saveProperties( doc, rendererElem );
|
||||
|
||||
if ( !mOrderBy.isEmpty() )
|
||||
{
|
||||
QDomElement orderBy = doc.createElement( "orderby" );
|
||||
mOrderBy.save( orderBy );
|
||||
rendererElem.appendChild( orderBy );
|
||||
}
|
||||
return rendererElem;
|
||||
}
|
||||
|
||||
|
@ -238,6 +238,7 @@ SET(QGIS_GUI_SRCS
|
||||
qgsnewvectorlayerdialog.cpp
|
||||
qgsnumericsortlistviewitem.cpp
|
||||
qgsoptionsdialogbase.cpp
|
||||
qgsorderbydialog.cpp
|
||||
qgsowssourceselect.cpp
|
||||
qgspixmaplabel.cpp
|
||||
qgspluginmanagerinterface.cpp
|
||||
@ -367,6 +368,7 @@ SET(QGIS_GUI_MOC_HDRS
|
||||
qgsnewnamedialog.h
|
||||
qgsnewvectorlayerdialog.h
|
||||
qgsoptionsdialogbase.h
|
||||
qgsorderbydialog.h
|
||||
qgsowssourceselect.h
|
||||
qgspixmaplabel.h
|
||||
qgspluginmanagerinterface.h
|
||||
|
178
src/gui/qgsorderbydialog.cpp
Normal file
178
src/gui/qgsorderbydialog.cpp
Normal file
@ -0,0 +1,178 @@
|
||||
/***************************************************************************
|
||||
qgosorderbydialog.cpp
|
||||
|
||||
---------------------
|
||||
begin : 20.12.2015
|
||||
copyright : (C) 2015 by Matthias Kuhn
|
||||
email : matthias@opengis.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsorderbydialog.h"
|
||||
|
||||
#include "qgsexpressionbuilderdialog.h"
|
||||
|
||||
#include <QTableWidget>
|
||||
#include <QCheckBox>
|
||||
#include <QKeyEvent>
|
||||
|
||||
QgsOrderByDialog::QgsOrderByDialog( QgsVectorLayer* layer, QWidget* parent )
|
||||
: QDialog( parent )
|
||||
, mLayer( layer )
|
||||
{
|
||||
setupUi( this );
|
||||
connect( mOrderByTableWidget, SIGNAL( cellDoubleClicked( int, int ) ), this, SLOT( onCellDoubleClicked( int, int ) ) );
|
||||
connect( mOrderByTableWidget, SIGNAL( cellChanged( int, int ) ), this, SLOT( onCellChanged( int, int ) ) );
|
||||
|
||||
mOrderByTableWidget->horizontalHeader()->setResizeMode( QHeaderView::Stretch );
|
||||
mOrderByTableWidget->horizontalHeader()->setResizeMode( 1, QHeaderView::Interactive );
|
||||
mOrderByTableWidget->horizontalHeader()->setResizeMode( 2, QHeaderView::Interactive );
|
||||
|
||||
mOrderByTableWidget->installEventFilter( this );
|
||||
}
|
||||
|
||||
void QgsOrderByDialog::setOrderBy( const QgsFeatureRequest::OrderBy& orderBy )
|
||||
{
|
||||
mOrderByTableWidget->clear();
|
||||
mOrderByTableWidget->setRowCount( orderBy.length() + 1 );
|
||||
|
||||
int i = 0;
|
||||
Q_FOREACH ( const QgsFeatureRequest::OrderByClause& orderByClause, orderBy )
|
||||
{
|
||||
QTableWidgetItem* expressionItem = new QTableWidgetItem( orderByClause.expression().expression() );
|
||||
QCheckBox* ascCheckBox = new QCheckBox();
|
||||
ascCheckBox->setChecked( orderByClause.ascending() );
|
||||
QCheckBox* nullsFirstCheckBox = new QCheckBox();
|
||||
nullsFirstCheckBox->setChecked( orderByClause.nullsFirst() );
|
||||
|
||||
mOrderByTableWidget->setItem( i, 0, expressionItem );
|
||||
mOrderByTableWidget->setCellWidget( i, 1, ascCheckBox );
|
||||
mOrderByTableWidget->setCellWidget( i, 2, nullsFirstCheckBox );
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
// Add an empty widget at the end
|
||||
QTableWidgetItem* expressionItem = new QTableWidgetItem( "" );
|
||||
QCheckBox* ascCheckBox = new QCheckBox();
|
||||
ascCheckBox->setChecked( true );
|
||||
QCheckBox* nullsFirstCheckBox = new QCheckBox();
|
||||
|
||||
mOrderByTableWidget->setItem( i, 0, expressionItem );
|
||||
mOrderByTableWidget->setCellWidget( i, 1, ascCheckBox );
|
||||
mOrderByTableWidget->setCellWidget( i, 2, nullsFirstCheckBox );
|
||||
}
|
||||
|
||||
QgsFeatureRequest::OrderBy QgsOrderByDialog::orderBy()
|
||||
{
|
||||
QgsFeatureRequest::OrderBy orderBys;
|
||||
|
||||
for ( int i = 0; i < mOrderByTableWidget->rowCount(); ++i )
|
||||
{
|
||||
QString expressionText = mOrderByTableWidget->item( i, 0 )->text();
|
||||
|
||||
if ( ! expressionText.isEmpty() )
|
||||
{
|
||||
bool asc = static_cast<QCheckBox*>( mOrderByTableWidget->cellWidget( i, 1 ) )->checkState();
|
||||
bool nullsFirst = static_cast<QCheckBox*>( mOrderByTableWidget->cellWidget( i, 2 ) )->checkState();
|
||||
QgsFeatureRequest::OrderByClause orderBy( expressionText, asc, nullsFirst );
|
||||
|
||||
orderBys << orderBy;
|
||||
}
|
||||
}
|
||||
|
||||
return orderBys;
|
||||
}
|
||||
|
||||
void QgsOrderByDialog::onCellDoubleClicked( int row, int column )
|
||||
{
|
||||
// Only act on first cell where the expression text is
|
||||
if ( 0 == column )
|
||||
{
|
||||
QgsExpressionBuilderDialog dlg( mLayer );
|
||||
|
||||
dlg.setExpressionText( mOrderByTableWidget->item( row, column )->text() );
|
||||
|
||||
if ( dlg.exec() )
|
||||
{
|
||||
QString expressionText = dlg.expressionText();
|
||||
|
||||
mOrderByTableWidget->item( row, column )->setText( expressionText );
|
||||
|
||||
if ( row == mOrderByTableWidget->rowCount() - 1 )
|
||||
{
|
||||
// Add an empty widget at the end if the last row was edited
|
||||
mOrderByTableWidget->insertRow( mOrderByTableWidget->rowCount() );
|
||||
|
||||
QTableWidgetItem* expressionItem = new QTableWidgetItem( "" );
|
||||
QCheckBox* ascCheckBox = new QCheckBox();
|
||||
ascCheckBox->setChecked( true );
|
||||
QCheckBox* nullsFirstCheckBox = new QCheckBox();
|
||||
|
||||
mOrderByTableWidget->setItem( row + 1, 0, expressionItem );
|
||||
mOrderByTableWidget->setCellWidget( row + 1, 1, ascCheckBox );
|
||||
mOrderByTableWidget->setCellWidget( row + 1, 2, nullsFirstCheckBox );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsOrderByDialog::onCellChanged( int row, int column )
|
||||
{
|
||||
// If the text was cleared
|
||||
if ( mOrderByTableWidget->item( row, column )->text().isEmpty() )
|
||||
{
|
||||
// If the first column (expression text) and not the last row was edited
|
||||
if ( 0 == column && row != mOrderByTableWidget->rowCount() - 1 )
|
||||
{
|
||||
{
|
||||
mOrderByTableWidget->removeRow( row );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If it's the last row and an expression was added: add a new empty one
|
||||
if ( row == mOrderByTableWidget->rowCount() - 1 && !mOrderByTableWidget->item( row, column )->text().isEmpty() )
|
||||
{
|
||||
// Add an empty widget at the end if the last row was edited
|
||||
mOrderByTableWidget->insertRow( mOrderByTableWidget->rowCount() );
|
||||
|
||||
QTableWidgetItem* expressionItem = new QTableWidgetItem( "" );
|
||||
QCheckBox* ascCheckBox = new QCheckBox();
|
||||
ascCheckBox->setChecked( true );
|
||||
QCheckBox* nullsFirstCheckBox = new QCheckBox();
|
||||
|
||||
mOrderByTableWidget->setItem( row + 1, 0, expressionItem );
|
||||
mOrderByTableWidget->setCellWidget( row + 1, 1, ascCheckBox );
|
||||
mOrderByTableWidget->setCellWidget( row + 1, 2, nullsFirstCheckBox );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsOrderByDialog::eventFilter( QObject* obj, QEvent* e )
|
||||
{
|
||||
Q_UNUSED( obj )
|
||||
Q_ASSERT( obj == mOrderByTableWidget );
|
||||
|
||||
if ( e->type() == QEvent::KeyPress )
|
||||
{
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>( e );
|
||||
|
||||
if ( keyEvent->key() == Qt::Key_Delete )
|
||||
{
|
||||
if ( mOrderByTableWidget->currentRow() != mOrderByTableWidget->rowCount() - 1 )
|
||||
mOrderByTableWidget->removeRow( mOrderByTableWidget->currentRow() );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
65
src/gui/qgsorderbydialog.h
Normal file
65
src/gui/qgsorderbydialog.h
Normal file
@ -0,0 +1,65 @@
|
||||
/***************************************************************************
|
||||
qgsorderbydialog.h
|
||||
|
||||
---------------------
|
||||
begin : 20.12.2015
|
||||
copyright : (C) 2015 by Matthias Kuhn
|
||||
email : matthias@opengis.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSORDERBYDIALOG_H
|
||||
#define QGSORDERBYDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include "qgsfeaturerequest.h"
|
||||
|
||||
#include "ui_qgsorderbydialogbase.h"
|
||||
|
||||
/**
|
||||
* This is a dialog to build and manage a list of order by clauses.
|
||||
*
|
||||
* @note added in 2.14
|
||||
*/
|
||||
|
||||
class GUI_EXPORT QgsOrderByDialog : public QDialog, private Ui::OrderByDialogBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create a new order by dialog. This helps building order by structures.
|
||||
*
|
||||
* @param layer The vector layer for which the order by should be produced
|
||||
* @param parent The parent widget, optional
|
||||
*/
|
||||
QgsOrderByDialog( QgsVectorLayer* layer, QWidget* parent = nullptr );
|
||||
|
||||
/**
|
||||
* Set the order by to manage
|
||||
*/
|
||||
void setOrderBy( const QgsFeatureRequest::OrderBy& orderBy );
|
||||
|
||||
/**
|
||||
* Get the order by defined in the dialog
|
||||
*/
|
||||
QgsFeatureRequest::OrderBy orderBy();
|
||||
|
||||
private slots:
|
||||
void onCellDoubleClicked( int row, int column );
|
||||
void onCellChanged( int row, int column );
|
||||
|
||||
private:
|
||||
QgsVectorLayer* mLayer;
|
||||
|
||||
bool eventFilter( QObject *obj, QEvent *e );
|
||||
};
|
||||
|
||||
#endif // QGSORDERBYDIALOG_H
|
@ -25,6 +25,7 @@
|
||||
#include "qgspointdisplacementrendererwidget.h"
|
||||
#include "qgsinvertedpolygonrendererwidget.h"
|
||||
#include "qgsheatmaprendererwidget.h"
|
||||
#include "qgsorderbydialog.h"
|
||||
|
||||
#include "qgsapplication.h"
|
||||
#include "qgslogger.h"
|
||||
@ -109,13 +110,17 @@ QgsRendererV2PropertiesDialog::QgsRendererV2PropertiesDialog( QgsVectorLayer* la
|
||||
connect( mLayerTransparencySpnBx, SIGNAL( valueChanged( int ) ), mLayerTransparencySlider, SLOT( setValue( int ) ) );
|
||||
|
||||
//paint effect widget
|
||||
if ( mLayer->rendererV2() && mLayer->rendererV2()->paintEffect() )
|
||||
if ( mLayer->rendererV2() )
|
||||
{
|
||||
mPaintEffect = mLayer->rendererV2()->paintEffect()->clone();
|
||||
mEffectWidget->setPaintEffect( mPaintEffect );
|
||||
if ( mLayer->rendererV2()->paintEffect() )
|
||||
{
|
||||
mPaintEffect = mLayer->rendererV2()->paintEffect()->clone();
|
||||
mEffectWidget->setPaintEffect( mPaintEffect );
|
||||
}
|
||||
|
||||
mOrderBy = mLayer->rendererV2()->orderBy();
|
||||
}
|
||||
|
||||
QPixmap pix;
|
||||
QgsRendererV2Registry* reg = QgsRendererV2Registry::instance();
|
||||
QStringList renderers = reg->renderersList();
|
||||
Q_FOREACH ( const QString& name, renderers )
|
||||
@ -128,21 +133,31 @@ QgsRendererV2PropertiesDialog::QgsRendererV2PropertiesDialog( QgsVectorLayer* la
|
||||
|
||||
// setup slot rendererChanged()
|
||||
connect( cboRenderers, SIGNAL( currentIndexChanged( int ) ), this, SLOT( rendererChanged() ) );
|
||||
//setup order by
|
||||
if ( mOrderBy.isEmpty() )
|
||||
{
|
||||
btnOrderBy->setEnabled( false );
|
||||
checkboxEnableOrderBy->setChecked( false );
|
||||
lineEditOrderBy->setEnabled( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
checkboxEnableOrderBy->setChecked( true );
|
||||
}
|
||||
lineEditOrderBy->setReadOnly( true );
|
||||
connect( checkboxEnableOrderBy, SIGNAL( toggled( bool ) ), btnOrderBy, SLOT( setEnabled( bool ) ) );
|
||||
connect( checkboxEnableOrderBy, SIGNAL( toggled( bool ) ), lineEditOrderBy, SLOT( setEnabled( bool ) ) );
|
||||
connect( btnOrderBy, SIGNAL( clicked( bool ) ), this, SLOT( showOrderByDialog() ) );
|
||||
lineEditOrderBy->setText( mOrderBy.dump() );
|
||||
|
||||
// set current renderer from layer
|
||||
QString rendererName = mLayer->rendererV2()->type();
|
||||
for ( int i = 0; i < cboRenderers->count(); i++ )
|
||||
{
|
||||
if ( cboRenderers->itemData( i ).toString() == rendererName )
|
||||
{
|
||||
cboRenderers->setCurrentIndex( i );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int rendererIdx = cboRenderers->findData( rendererName );
|
||||
cboRenderers->setCurrentIndex( rendererIdx );
|
||||
|
||||
// no renderer found... this mustn't happen
|
||||
Q_ASSERT( false && "there must be a renderer!" );
|
||||
|
||||
Q_ASSERT( rendererIdx != -1 && "there must be a renderer!" );
|
||||
}
|
||||
|
||||
QgsRendererV2PropertiesDialog::~QgsRendererV2PropertiesDialog()
|
||||
@ -223,6 +238,9 @@ void QgsRendererV2PropertiesDialog::apply()
|
||||
if ( renderer )
|
||||
{
|
||||
renderer->setPaintEffect( mPaintEffect->clone() );
|
||||
// set the order by
|
||||
renderer->setOrderBy( mOrderBy );
|
||||
|
||||
mLayer->setRendererV2( renderer->clone() );
|
||||
}
|
||||
|
||||
@ -240,6 +258,18 @@ void QgsRendererV2PropertiesDialog::onOK()
|
||||
accept();
|
||||
}
|
||||
|
||||
void QgsRendererV2PropertiesDialog::showOrderByDialog()
|
||||
{
|
||||
QgsOrderByDialog dlg( mLayer );
|
||||
|
||||
dlg.setOrderBy( mOrderBy );
|
||||
if ( dlg.exec() )
|
||||
{
|
||||
mOrderBy = dlg.orderBy();
|
||||
lineEditOrderBy->setText( mOrderBy.dump() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QgsRendererV2PropertiesDialog::keyPressEvent( QKeyEvent * e )
|
||||
{
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include "ui_qgsrendererv2propsdialogbase.h"
|
||||
|
||||
#include "qgsfeaturerequest.h"
|
||||
|
||||
class QKeyEvent;
|
||||
|
||||
class QgsVectorLayer;
|
||||
@ -52,6 +54,9 @@ class GUI_EXPORT QgsRendererV2PropertiesDialog : public QDialog, private Ui::Qgs
|
||||
void apply();
|
||||
void onOK();
|
||||
|
||||
private slots:
|
||||
void showOrderByDialog();
|
||||
|
||||
protected:
|
||||
|
||||
//! Reimplements dialog keyPress event so we can ignore it
|
||||
@ -66,6 +71,8 @@ class GUI_EXPORT QgsRendererV2PropertiesDialog : public QDialog, private Ui::Qgs
|
||||
QgsPaintEffect* mPaintEffect;
|
||||
|
||||
QgsMapCanvas* mMapCanvas;
|
||||
|
||||
QgsFeatureRequest::OrderBy mOrderBy;
|
||||
};
|
||||
|
||||
|
||||
|
89
src/ui/qgsorderbydialogbase.ui
Normal file
89
src/ui/qgsorderbydialogbase.ui
Normal file
@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OrderByDialogBase</class>
|
||||
<widget class="QDialog" name="OrderByDialogBase">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>747</width>
|
||||
<height>296</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Define order</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QTableWidget" name="mOrderByTableWidget">
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Expression</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Ascending</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Nulls First</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>OrderByDialogBase</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>OrderByDialogBase</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -85,6 +85,16 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="0" colspan="4">
|
||||
<widget class="QgsEffectStackCompactWidget" name="mEffectWidget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
@ -133,15 +143,30 @@
|
||||
<item row="1" column="1">
|
||||
<widget class="QgsBlendModeComboBox" name="mBlendModeComboBox"/>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QgsEffectStackCompactWidget" name="mEffectWidget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
<item row="3" column="0" colspan="4">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkboxEnableOrderBy">
|
||||
<property name="text">
|
||||
<string>Control feature rendering order</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditOrderBy">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="btnOrderBy">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
Loading…
x
Reference in New Issue
Block a user