Skip to content

Commit 72b3812

Browse files
committedApr 4, 2014
Merge remote-tracking branch 'denis/layerfieldmodel'
2 parents a43bd62 + a95fedb commit 72b3812

28 files changed

+1340
-188
lines changed
 

‎python/core/composer/qgsatlascomposition.sip

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,11 @@ public:
6868
QString featureFilter() const;
6969
void setFeatureFilter( const QString& expression );
7070

71-
int sortKeyAttributeIndex() const;
72-
void setSortKeyAttributeIndex( int idx );
71+
QString sortKeyAttributeName() const;
72+
void setSortKeyAttributeName( QString fieldName );
73+
74+
int sortKeyAttributeIndex() const /Deprecated/;
75+
void setSortKeyAttributeIndex( int idx ) /Deprecated/;
7376

7477
/** Begins the rendering. Returns true if successful, false if no matching atlas
7578
features found.*/

‎python/gui/gui.sip

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
%Include qgsexpressionbuilderdialog.sip
2929
%Include qgsexpressionbuilderwidget.sip
3030
%Include qgsexpressionhighlighter.sip
31+
%Include qgsfieldcombobox.sip
32+
%Include qgsfieldmodel.sip
3133
%Include qgsfieldvalidator.sip
3234
%Include qgsfiledropedit.sip
3335
%Include qgsfilterlineedit.sip
@@ -44,6 +46,9 @@
4446
%Include qgsmapcanvasmap.sip
4547
%Include qgsmapcanvassnapper.sip
4648
%Include qgsmaplayeractionregistry.sip
49+
%Include qgsmaplayercombobox.sip
50+
%Include qgsmaplayermodel.sip
51+
%Include qgsmaplayerproxymodel.sip
4752
%Include qgsmapoverviewcanvas.sip
4853
%Include qgsmaptip.sip
4954
%Include qgsmaptool.sip

‎python/gui/qgsfieldcombobox.sip

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* @brief The QgsFieldComboBox is a combo box which displays the list of fields of a given layer.
3+
* @note added in 2.3
4+
*/
5+
class QgsFieldComboBox : QComboBox
6+
{
7+
8+
%TypeHeaderCode
9+
#include "qgsfieldcombobox.h"
10+
%End
11+
12+
public:
13+
/**
14+
* @brief QgsFieldComboBox creates a combo box to display the fields of a layer.
15+
* The layer can be either manually given or dynamically set by connecting the signal QgsMapLayerComboBox::layerChanged to the slot setLayer.
16+
*/
17+
explicit QgsFieldComboBox( QWidget *parent /TransferThis/ = 0 );
18+
19+
/**
20+
* @brief currentField returns the currently selected field
21+
*/
22+
QString currentField();
23+
24+
signals:
25+
/**
26+
* @brief fieldChanged the signal is emitted when the currently selected field changes
27+
*/
28+
void fieldChanged( QString fieldName );
29+
30+
public slots:
31+
/**
32+
* @brief setLayer sets the layer of which the fields are listed
33+
*/
34+
void setLayer( QgsMapLayer* layer );
35+
/**
36+
* @brief setField sets the currently selected field
37+
*/
38+
void setField( QString fieldName );
39+
40+
};

‎python/gui/qgsfieldmodel.sip

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
/**
3+
* @brief The QgsFieldModel class is a model to display the list of fields of a layer in widgets.
4+
* It can be associated with a QgsMapLayerModel to dynamically display a layer and its fields.
5+
* @note added in 2.3
6+
*/
7+
8+
class QgsFieldModel : QAbstractItemModel
9+
{
10+
%TypeHeaderCode
11+
#include "qgsfieldmodel.h"
12+
%End
13+
14+
public:
15+
static const int FieldNameRole;
16+
static const int FieldIndexRole;
17+
18+
/**
19+
* @brief QgsFieldModel creates a model to display the fields of a given layer
20+
*/
21+
explicit QgsFieldModel( QObject *parent /TransferThis/ = 0 );
22+
23+
/**
24+
* @brief indexFromName returns the index corresponding to a given fieldName
25+
*/
26+
QModelIndex indexFromName( QString fieldName );
27+
28+
public slots:
29+
/**
30+
* @brief setLayer sets the layer of whch fields are displayed
31+
*/
32+
void setLayer( QgsMapLayer *layer );
33+
34+
// QAbstractItemModel interface
35+
public:
36+
QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const;
37+
QModelIndex parent( const QModelIndex &child ) const;
38+
int rowCount( const QModelIndex &parent ) const;
39+
int columnCount( const QModelIndex &parent ) const;
40+
QVariant data( const QModelIndex &index, int role ) const;
41+
42+
};

‎python/gui/qgsmaplayercombobox.sip

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* @brief The QgsMapLayerComboBox class is a combo box which displays the list of layers
3+
* @note added in 2.3
4+
*/
5+
class QgsMapLayerComboBox : QComboBox
6+
{
7+
8+
%TypeHeaderCode
9+
#include "qgsmaplayercombobox.h"
10+
%End
11+
12+
public:
13+
/**
14+
* @brief QgsMapLayerComboBox creates a combo box to dislpay the list of layers (currently in the registry).
15+
* The layers can be filtered and/or ordered.
16+
*/
17+
explicit QgsMapLayerComboBox( QWidget *parent /TransferThis/ = 0 );
18+
19+
/**
20+
* @brief setFilters allows fitering according to layer type and/or geometry type.
21+
*/
22+
void setFilters( QgsMapLayerProxyModel::Filters filters );
23+
24+
/**
25+
* @brief currentLayer returns the current layer selected in the combo box
26+
*/
27+
QgsMapLayer* currentLayer();
28+
29+
public slots:
30+
/**
31+
* @brief setLayer set the current layer selected in the combo
32+
*/
33+
void setLayer( QgsMapLayer* layer );
34+
35+
signals:
36+
/**
37+
* @brief layerChanged this signal is emitted whenever the currently selected layer changes
38+
*/
39+
void layerChanged( QgsMapLayer* layer );
40+
};

‎python/gui/qgsmaplayermodel.sip

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
2+
/**
3+
* @brief The QgsMapLayerModel class is a model to display layers in widgets.
4+
* @see QgsMapLayerProxyModel to sort and/filter the layers
5+
* @see QgsFieldModel to combine in with a field selector.
6+
* @note added in 2.3
7+
*/
8+
class QgsMapLayerModel : QAbstractItemModel
9+
{
10+
11+
%TypeHeaderCode
12+
#include "qgsmaplayermodel.h"
13+
%End
14+
15+
public:
16+
static const int LayerIdRole;
17+
18+
/**
19+
* @brief QgsMapLayerModel creates a model to display layers in widgets.
20+
*/
21+
explicit QgsMapLayerModel( QObject *parent /TransferThis/ = 0 );
22+
/**
23+
* @brief QgsMapLayerModel creates a model to display a specific list of layers in a widget.
24+
*/
25+
explicit QgsMapLayerModel( QList<QgsMapLayer*> layers, QObject *parent /TransferThis/ = 0 );
26+
27+
/**
28+
* @brief setItemsCheckable defines if layers should be selectable in the widget
29+
*/
30+
void setItemsCheckable( bool checkable );
31+
/**
32+
* @brief checkAll changes the checkstate for all the layers
33+
*/
34+
void checkAll( Qt::CheckState checkState );
35+
/**
36+
* @brief layersChecked returns the list of layers which are checked (or unchecked)
37+
*/
38+
QList<QgsMapLayer*> layersChecked( Qt::CheckState checkState = Qt::Checked );
39+
//! returns if the items can be checked or not
40+
bool itemsCheckable() ;
41+
42+
/**
43+
* @brief indexFromLayer returns the model index for a given layer
44+
*/
45+
QModelIndex indexFromLayer( QgsMapLayer* layer );
46+
47+
// QAbstractItemModel interface
48+
public:
49+
QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const;
50+
QModelIndex parent( const QModelIndex &child ) const;
51+
int rowCount( const QModelIndex &parent ) const;
52+
int columnCount( const QModelIndex &parent ) const;
53+
QVariant data( const QModelIndex &index, int role ) const;
54+
bool setData( const QModelIndex &index, const QVariant &value, int role );
55+
Qt::ItemFlags flags( const QModelIndex &index ) const;
56+
};
57+
58+

‎python/gui/qgsmaplayerproxymodel.sip

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* @brief The QgsMapLayerProxModel class provides an easy to use model to display the list of layers in widgets.
3+
* @note added in 2.3
4+
*/
5+
class QgsMapLayerProxyModel : QSortFilterProxyModel
6+
{
7+
8+
%TypeHeaderCode
9+
#include "qgsmaplayerproxymodel.h"
10+
%End
11+
12+
public:
13+
enum Filter
14+
{
15+
NoFilter = 1,
16+
RasterLayer = 2,
17+
NoGeometry = 4,
18+
PointLayer = 8,
19+
LineLayer = 16,
20+
PolygonLayer = 32,
21+
HasGeometry = 56,
22+
VectorLayer = 60
23+
};
24+
typedef QFlags<QgsMapLayerProxyModel::Filter> Filters;
25+
26+
/**
27+
* @brief QgsMapLayerProxModel creates a proxy model with a QgsMapLayerModel as source model.
28+
* It can be used to filter the layers list in a widget.
29+
*/
30+
explicit QgsMapLayerProxyModel( QObject *parent /TransferThis/ = 0 );
31+
32+
/**
33+
* @brief layerModel returns the QgsMapLayerModel used in this QSortFilterProxyModel
34+
*/
35+
QgsMapLayerModel* sourceLayerModel() ;
36+
37+
/**
38+
* @brief setFilters set flags that affect how layers are filtered
39+
* @param filters are Filter flags
40+
* @note added in 2.3
41+
*/
42+
QgsMapLayerProxyModel* setFilters( Filters filters );
43+
const Filters& filters() const ;
44+
45+
// QSortFilterProxyModel interface
46+
public:
47+
bool filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const;
48+
bool lessThan( const QModelIndex &left, const QModelIndex &right ) const;
49+
};
50+

‎src/app/composer/qgsatlascompositionwidget.cpp

Lines changed: 18 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
#include "qgsatlascompositionwidget.h"
2020
#include "qgsatlascomposition.h"
2121
#include "qgscomposition.h"
22+
#include "qgsfieldmodel.h"
2223
#include "qgsmaplayerregistry.h"
24+
#include "qgsmaplayerproxymodel.h"
2325
#include "qgsexpressionbuilderdialog.h"
2426
#include "qgscomposermap.h"
2527

@@ -28,28 +30,11 @@ QgsAtlasCompositionWidget::QgsAtlasCompositionWidget( QWidget* parent, QgsCompos
2830
{
2931
setupUi( this );
3032

31-
// populate the layer list
32-
mAtlasCoverageLayerComboBox->clear();
33-
const QMap< QString, QgsMapLayer * >& layers = QgsMapLayerRegistry::instance()->mapLayers();
34-
int idx = 0;
35-
for ( QMap<QString, QgsMapLayer*>::const_iterator it = layers.begin(); it != layers.end(); ++it )
36-
{
37-
// Only consider vector layers
38-
if ( dynamic_cast<QgsVectorLayer*>( it.value() ) )
39-
{
40-
mAtlasCoverageLayerComboBox->insertItem( idx++, it.value()->name(), /* userdata */ qVariantFromValue(( void* )it.value() ) );
41-
}
42-
}
43-
// update sort columns
44-
fillSortColumns();
45-
46-
// Connect to addition / removal of layers
47-
QgsMapLayerRegistry* layerRegistry = QgsMapLayerRegistry::instance();
48-
if ( layerRegistry )
49-
{
50-
connect( layerRegistry, SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( onLayerRemoved( QString ) ) );
51-
connect( layerRegistry, SIGNAL( layerWasAdded( QgsMapLayer* ) ), this, SLOT( onLayerAdded( QgsMapLayer* ) ) );
52-
}
33+
mAtlasCoverageLayerComboBox->setFilters( QgsMapLayerProxyModel::HasGeometry );
34+
mAtlasSortFeatureKeyComboBox->setLayer( mAtlasCoverageLayerComboBox->currentLayer() );
35+
connect( mAtlasCoverageLayerComboBox, SIGNAL( layerChanged( QgsMapLayer* ) ), mAtlasSortFeatureKeyComboBox, SLOT( setLayer( QgsMapLayer* ) ) );
36+
connect( mAtlasCoverageLayerComboBox, SIGNAL( layerChanged( QgsMapLayer* ) ), this, SLOT( changeCoverageLayer( QgsMapLayer* ) ) );
37+
connect( mAtlasSortFeatureKeyComboBox, SIGNAL( fieldChanged( QString ) ), this, SLOT( changesSortFeatureField( QString ) ) );
5338

5439
// Sort direction
5540
mAtlasSortFeatureDirectionButton->setEnabled( false );
@@ -82,68 +67,24 @@ void QgsAtlasCompositionWidget::on_mUseAtlasCheckBox_stateChanged( int state )
8267
}
8368
}
8469

85-
void QgsAtlasCompositionWidget::onLayerRemoved( QString layerName )
86-
{
87-
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
88-
// update the atlas coverage layer combo box
89-
for ( int i = 0; i < mAtlasCoverageLayerComboBox->count(); ++i )
90-
{
91-
const QgsMapLayer* layer = reinterpret_cast<const QgsMapLayer*>( mAtlasCoverageLayerComboBox->itemData( i ).value<void*>() );
92-
if ( layer->id() == layerName )
93-
{
94-
mAtlasCoverageLayerComboBox->removeItem( i );
95-
break;
96-
}
97-
}
98-
if ( mAtlasCoverageLayerComboBox->count() == 0 )
99-
{
100-
atlasMap->setCoverageLayer( 0 );
101-
}
102-
}
103-
104-
void QgsAtlasCompositionWidget::onLayerAdded( QgsMapLayer* map )
105-
{
106-
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
107-
// update the atlas coverage layer combo box
108-
QgsVectorLayer* vectorLayer = dynamic_cast<QgsVectorLayer*>( map );
109-
if ( vectorLayer )
110-
{
111-
mAtlasCoverageLayerComboBox->addItem( map->name(), qVariantFromValue(( void* )map ) );
112-
113-
if ( mAtlasCoverageLayerComboBox->count() == 1 )
114-
{
115-
atlasMap->setCoverageLayer( vectorLayer );
116-
updateAtlasFeatures();
117-
}
118-
}
119-
}
120-
121-
void QgsAtlasCompositionWidget::on_mAtlasCoverageLayerComboBox_currentIndexChanged( int index )
70+
void QgsAtlasCompositionWidget::changeCoverageLayer( QgsMapLayer *layer )
12271
{
12372
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
12473
if ( !atlasMap )
12574
{
12675
return;
12776
}
128-
if ( index == -1 )
77+
78+
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( layer );
79+
80+
if ( !vl )
12981
{
13082
atlasMap->setCoverageLayer( 0 );
131-
132-
// clean up the sorting columns
133-
mAtlasSortFeatureKeyComboBox->clear();
13483
}
13584
else
13685
{
137-
QgsVectorLayer* layer = reinterpret_cast<QgsVectorLayer*>( mAtlasCoverageLayerComboBox->itemData( index ).value<void*>() );
138-
139-
if ( layer )
140-
{
141-
atlasMap->setCoverageLayer( layer );
142-
updateAtlasFeatures();
143-
}
144-
145-
// update sorting columns
146-
fillSortColumns();
86+
atlasMap->setCoverageLayer( vl );
87+
updateAtlasFeatures();
14788
}
14889
}
14990

@@ -260,18 +201,14 @@ void QgsAtlasCompositionWidget::updateAtlasFeatures()
260201
}
261202
}
262203

263-
void QgsAtlasCompositionWidget::on_mAtlasSortFeatureKeyComboBox_currentIndexChanged( int index )
204+
void QgsAtlasCompositionWidget::changesSortFeatureField( QString fieldName )
264205
{
265206
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
266207
if ( !atlasMap )
267208
{
268209
return;
269210
}
270-
271-
if ( index != -1 )
272-
{
273-
atlasMap->setSortKeyAttributeIndex( index );
274-
}
211+
atlasMap->setSortKeyAttributeName( fieldName );
275212
updateAtlasFeatures();
276213
}
277214

@@ -347,23 +284,6 @@ void QgsAtlasCompositionWidget::on_mAtlasSortFeatureDirectionButton_clicked()
347284
updateAtlasFeatures();
348285
}
349286

350-
void QgsAtlasCompositionWidget::fillSortColumns()
351-
{
352-
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
353-
if ( !atlasMap || !atlasMap->coverageLayer() )
354-
{
355-
return;
356-
}
357-
358-
mAtlasSortFeatureKeyComboBox->clear();
359-
// Get fields of the selected coverage layer
360-
const QgsFields& fields = atlasMap->coverageLayer()->pendingFields();
361-
for ( int i = 0; i < fields.count(); ++i )
362-
{
363-
mAtlasSortFeatureKeyComboBox->insertItem( i, fields.at( i ).name() );
364-
}
365-
}
366-
367287
void QgsAtlasCompositionWidget::updateGuiElements()
368288
{
369289
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
@@ -376,17 +296,12 @@ void QgsAtlasCompositionWidget::updateGuiElements()
376296
mUseAtlasCheckBox->setCheckState( Qt::Unchecked );
377297
}
378298

379-
int idx = mAtlasCoverageLayerComboBox->findData( qVariantFromValue(( void* )atlasMap->coverageLayer() ) );
380-
if ( idx != -1 )
381-
{
382-
mAtlasCoverageLayerComboBox->setCurrentIndex( idx );
383-
}
384-
299+
mAtlasCoverageLayerComboBox->setLayer( atlasMap->coverageLayer() );
300+
mAtlasSortFeatureKeyComboBox->setField( atlasMap->sortKeyAttributeName() );
385301
mAtlasFilenamePatternEdit->setText( atlasMap->filenamePattern() );
386302
mAtlasHideCoverageCheckBox->setCheckState( atlasMap->hideCoverage() ? Qt::Checked : Qt::Unchecked );
387303
mAtlasSingleFileCheckBox->setCheckState( atlasMap->singleFile() ? Qt::Checked : Qt::Unchecked );
388304
mAtlasSortFeatureCheckBox->setCheckState( atlasMap->sortFeatures() ? Qt::Checked : Qt::Unchecked );
389-
mAtlasSortFeatureKeyComboBox->setCurrentIndex( atlasMap->sortKeyAttributeIndex() );
390305
mAtlasSortFeatureDirectionButton->setArrowType( atlasMap->sortAscending() ? Qt::UpArrow : Qt::DownArrow );
391306
mAtlasFeatureFilterEdit->setText( atlasMap->featureFilter() );
392307
mAtlasFeatureFilterCheckBox->setCheckState( atlasMap->filterFeatures() ? Qt::Checked : Qt::Unchecked );

‎src/app/composer/qgsatlascompositionwidget.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,25 +36,20 @@ class QgsAtlasCompositionWidget:
3636

3737
public slots:
3838
void on_mUseAtlasCheckBox_stateChanged( int state );
39-
void on_mAtlasCoverageLayerComboBox_currentIndexChanged( int index );
39+
void changeCoverageLayer( QgsMapLayer* layer );
4040
void on_mAtlasFilenamePatternEdit_textChanged( const QString& text );
4141
void on_mAtlasFilenameExpressionButton_clicked();
4242
void on_mAtlasHideCoverageCheckBox_stateChanged( int state );
4343
void on_mAtlasSingleFileCheckBox_stateChanged( int state );
4444

4545
void on_mAtlasSortFeatureCheckBox_stateChanged( int state );
46-
void on_mAtlasSortFeatureKeyComboBox_currentIndexChanged( int index );
46+
void changesSortFeatureField( QString fieldName );
4747
void on_mAtlasSortFeatureDirectionButton_clicked();
4848
void on_mAtlasFeatureFilterEdit_editingFinished();
4949
void on_mAtlasFeatureFilterButton_clicked();
5050
void on_mAtlasFeatureFilterCheckBox_stateChanged( int state );
5151

52-
// extract fields from the current coverage layer and populate the corresponding combo box
53-
void fillSortColumns();
5452
private slots:
55-
void onLayerRemoved( QString );
56-
void onLayerAdded( QgsMapLayer* );
57-
5853
void updateGuiElements();
5954

6055
void updateAtlasFeatures();

‎src/app/qgisapp.cpp

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3758,29 +3758,11 @@ void QgisApp::fileSaveAs()
37583758

37593759
void QgisApp::dxfExport()
37603760
{
3761-
QgsLegend* mapLegend = legend();
3762-
if ( !mapLegend )
3763-
{
3764-
return;
3765-
}
3766-
3767-
QgsDxfExportDialog d( mapLegend->layers() );
3761+
QgsDxfExportDialog d;
37683762
if ( d.exec() == QDialog::Accepted )
37693763
{
37703764
QgsDxfExport dxfExport;
3771-
3772-
QList<QgsMapLayer*> layerList;
3773-
QList<QString> layerIdList = d.layers();
3774-
QList<QString>::const_iterator layerIt = layerIdList.constBegin();
3775-
for ( ; layerIt != layerIdList.constEnd(); ++layerIt )
3776-
{
3777-
QgsMapLayer* l = QgsMapLayerRegistry::instance()->mapLayer( *layerIt );
3778-
if ( l )
3779-
{
3780-
layerList.append( l );
3781-
}
3782-
}
3783-
3765+
QList<QgsMapLayer*> layerList = d.layers();
37843766
dxfExport.addLayers( layerList );
37853767
dxfExport.setSymbologyScaleDenominator( d.symbologyScale() );
37863768
dxfExport.setSymbologyExport( d.symbologyMode() );

‎src/app/qgsdxfexportdialog.cpp

Lines changed: 12 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,41 +17,28 @@
1717

1818
#include "qgsdxfexportdialog.h"
1919
#include "qgsmaplayer.h"
20+
#include "qgsmaplayermodel.h"
2021
#include "qgsmaplayerregistry.h"
2122
#include "qgsvectorlayer.h"
2223
#include "qgis.h"
2324
#include <QFileDialog>
2425
#include <QPushButton>
2526
#include <QSettings>
2627

27-
QgsDxfExportDialog::QgsDxfExportDialog( const QList<QgsMapLayer*>& layerKeys, QWidget* parent, Qt::WindowFlags f ): QDialog( parent, f )
28+
QgsDxfExportDialog::QgsDxfExportDialog( QWidget* parent, Qt::WindowFlags f ): QDialog( parent, f )
2829
{
2930
setupUi( this );
31+
32+
mModel = new QgsMapLayerProxyModel( this );
33+
mModel->sourceLayerModel()->setItemsCheckable( true );
34+
mModel->setFilters( QgsMapLayerProxyModel::HasGeometry );
35+
mLayersListView->setModel( mModel );
36+
3037
connect( mFileLineEdit, SIGNAL( textChanged( const QString& ) ), this, SLOT( setOkEnabled() ) );
3138
connect( this, SIGNAL( accepted() ), this, SLOT( saveSettings() ) );
3239
connect( mSelectAllButton, SIGNAL( clicked() ), this, SLOT( selectAll() ) );
3340
connect( mUnSelectAllButton, SIGNAL( clicked() ), this, SLOT( unSelectAll() ) );
3441

35-
QList<QgsMapLayer*>::const_iterator layerIt = layerKeys.constBegin();
36-
for ( ; layerIt != layerKeys.constEnd(); ++layerIt )
37-
{
38-
QgsMapLayer* layer = *layerIt;
39-
if ( layer )
40-
{
41-
if ( layer->type() == QgsMapLayer::VectorLayer )
42-
{
43-
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( layer );
44-
if ( !vl->hasGeometryType() )
45-
continue;
46-
QListWidgetItem* layerItem = new QListWidgetItem( layer->name() );
47-
layerItem->setData( Qt::UserRole, layer->id() );
48-
layerItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
49-
layerItem->setCheckState( Qt::Checked );
50-
mLayersListWidget->addItem( layerItem );
51-
}
52-
}
53-
}
54-
5542
//last dxf symbology mode
5643
QSettings s;
5744
mSymbologyModeComboBox->setCurrentIndex( s.value( "qgis/lastDxfSymbologyMode", "2" ).toInt() );
@@ -64,34 +51,21 @@ QgsDxfExportDialog::QgsDxfExportDialog( const QList<QgsMapLayer*>& layerKeys, QW
6451

6552
QgsDxfExportDialog::~QgsDxfExportDialog()
6653
{
67-
6854
}
6955

7056
void QgsDxfExportDialog::selectAll()
7157
{
72-
for ( int r = 0; r < mLayersListWidget->count(); r++ )
73-
mLayersListWidget->item( r )->setCheckState( Qt::Checked );
58+
mModel->sourceLayerModel()->checkAll( Qt::Checked );
7459
}
7560

7661
void QgsDxfExportDialog::unSelectAll()
7762
{
78-
for ( int r = 0; r < mLayersListWidget->count(); r++ )
79-
mLayersListWidget->item( r )->setCheckState( Qt::Unchecked );
63+
mModel->sourceLayerModel()->checkAll( Qt::Unchecked );
8064
}
8165

82-
QList<QString> QgsDxfExportDialog::layers() const
66+
QList<QgsMapLayer*> QgsDxfExportDialog::layers() const
8367
{
84-
QList<QString> layerKeyList;
85-
int nItems = mLayersListWidget->count();
86-
for ( int i = 0; i < nItems; ++i )
87-
{
88-
QListWidgetItem* currentItem = mLayersListWidget->item( i );
89-
if ( currentItem->checkState() == Qt::Checked )
90-
{
91-
layerKeyList.prepend( currentItem->data( Qt::UserRole ).toString() );
92-
}
93-
}
94-
return layerKeyList;
68+
return mModel->sourceLayerModel()->layersChecked();
9569
}
9670

9771
double QgsDxfExportDialog::symbologyScale() const

‎src/app/qgsdxfexportdialog.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,16 @@
2020

2121
#include "ui_qgsdxfexportdialogbase.h"
2222
#include "qgsdxfexport.h"
23+
#include "qgsmaplayerproxymodel.h"
2324

2425
class QgsDxfExportDialog: public QDialog, private Ui::QgsDxfExportDialogBase
2526
{
2627
Q_OBJECT
2728
public:
28-
QgsDxfExportDialog( const QList<QgsMapLayer*>& layerKeys, QWidget * parent = 0, Qt::WindowFlags f = 0 );
29+
QgsDxfExportDialog( QWidget * parent = 0, Qt::WindowFlags f = 0 );
2930
~QgsDxfExportDialog();
3031

31-
QList<QString> layers() const;
32+
QList<QgsMapLayer *> layers() const;
3233
double symbologyScale() const;
3334
QgsDxfExport::SymbologyExport symbologyMode() const;
3435
QString saveFile() const;
@@ -43,6 +44,9 @@ class QgsDxfExportDialog: public QDialog, private Ui::QgsDxfExportDialogBase
4344
void on_mFileSelectionButton_clicked();
4445
void setOkEnabled();
4546
void saveSettings();
47+
48+
private:
49+
QgsMapLayerProxyModel* mModel;
4650
};
4751

4852
#endif // QGSDXFEXPORTDIALOG_H

‎src/core/composer/qgsatlascomposition.cpp

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ void QgsAtlasComposition::setCoverageLayer( QgsVectorLayer* layer )
6565
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )mFeatureIds.size() ) );
6666

6767
// Grab the first feature so that user can use it to test the style in rules.
68-
if( layer )
68+
if ( layer )
6969
{
7070
QgsFeature fet;
7171
layer->getFeatures().nextFeature( fet );
@@ -155,6 +155,29 @@ void QgsAtlasComposition::setMargin( float margin )
155155
map->setAtlasMargin(( double ) margin );
156156
}
157157

158+
int QgsAtlasComposition::sortKeyAttributeIndex() const
159+
{
160+
if ( !mCoverageLayer )
161+
{
162+
return -1;
163+
}
164+
return mCoverageLayer->fieldNameIndex( mSortKeyAttributeName );
165+
}
166+
167+
void QgsAtlasComposition::setSortKeyAttributeIndex( int idx )
168+
{
169+
if ( mCoverageLayer )
170+
{
171+
const QgsFields fields = mCoverageLayer->pendingFields();
172+
if ( idx >= 0 && idx < fields.count() )
173+
{
174+
mSortKeyAttributeName = fields[idx].name();
175+
return;
176+
}
177+
}
178+
mSortKeyAttributeName = "";
179+
}
180+
158181
//
159182
// Private class only used for the sorting of features
160183
class FieldSorter
@@ -215,6 +238,7 @@ int QgsAtlasComposition::updateFeatures()
215238
QgsFeature feat;
216239
mFeatureIds.clear();
217240
mFeatureKeys.clear();
241+
int sortIdx = mCoverageLayer->fieldNameIndex( mSortKeyAttributeName );
218242
while ( fit.nextFeature( feat ) )
219243
{
220244
if ( mFilterFeatures && !mFeatureFilter.isEmpty() )
@@ -233,14 +257,14 @@ int QgsAtlasComposition::updateFeatures()
233257
}
234258
mFeatureIds.push_back( feat.id() );
235259

236-
if ( mSortFeatures )
260+
if ( mSortFeatures && sortIdx != -1 )
237261
{
238-
mFeatureKeys.insert( feat.id(), feat.attributes()[ mSortKeyAttributeIdx ] );
262+
mFeatureKeys.insert( feat.id(), feat.attributes()[ sortIdx ] );
239263
}
240264
}
241265

242266
// sort features, if asked for
243-
if ( mSortFeatures )
267+
if ( mFeatureKeys.count() )
244268
{
245269
FieldSorter sorter( mFeatureKeys, mSortAscending );
246270
qSort( mFeatureIds.begin(), mFeatureIds.end(), sorter );
@@ -567,7 +591,7 @@ void QgsAtlasComposition::writeXML( QDomElement& elem, QDomDocument& doc ) const
567591
atlasElem.setAttribute( "sortFeatures", mSortFeatures ? "true" : "false" );
568592
if ( mSortFeatures )
569593
{
570-
atlasElem.setAttribute( "sortKey", QString::number( mSortKeyAttributeIdx ) );
594+
atlasElem.setAttribute( "sortKey", mSortKeyAttributeName );
571595
atlasElem.setAttribute( "sortAscending", mSortAscending ? "true" : "false" );
572596
}
573597
atlasElem.setAttribute( "filterFeatures", mFilterFeatures ? "true" : "false" );
@@ -637,7 +661,20 @@ void QgsAtlasComposition::readXML( const QDomElement& atlasElem, const QDomDocum
637661
mSortFeatures = atlasElem.attribute( "sortFeatures", "false" ) == "true" ? true : false;
638662
if ( mSortFeatures )
639663
{
640-
mSortKeyAttributeIdx = atlasElem.attribute( "sortKey", "0" ).toInt();
664+
mSortKeyAttributeName = atlasElem.attribute( "sortKey", "" );
665+
// since 2.3, the field name is saved instead of the field index
666+
// following code keeps compatibility with version 2.2 projects
667+
// to be removed in QGIS 3.0
668+
bool isIndex;
669+
int idx = mSortKeyAttributeName.toInt( &isIndex );
670+
if ( isIndex && mCoverageLayer )
671+
{
672+
const QgsFields fields = mCoverageLayer->pendingFields();
673+
if ( idx >= 0 && idx < fields.count() )
674+
{
675+
mSortKeyAttributeName = fields[idx].name();
676+
}
677+
}
641678
mSortAscending = atlasElem.attribute( "sortAscending", "true" ) == "true" ? true : false;
642679
}
643680
mFilterFeatures = atlasElem.attribute( "filterFeatures", "false" ) == "true" ? true : false;

‎src/core/composer/qgsatlascomposition.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,11 @@ class CORE_EXPORT QgsAtlasComposition : public QObject
9696
QString featureFilter() const { return mFeatureFilter; }
9797
void setFeatureFilter( const QString& expression ) { mFeatureFilter = expression; }
9898

99-
int sortKeyAttributeIndex() const { return mSortKeyAttributeIdx; }
100-
void setSortKeyAttributeIndex( int idx ) { mSortKeyAttributeIdx = idx; }
99+
QString sortKeyAttributeName() const { return mSortKeyAttributeName; }
100+
void setSortKeyAttributeName( QString fieldName ) { mSortKeyAttributeName = fieldName; }
101+
102+
Q_DECL_DEPRECATED int sortKeyAttributeIndex() const;
103+
Q_DECL_DEPRECATED void setSortKeyAttributeIndex( int idx );
101104

102105
/** Begins the rendering. Returns true if successful, false if no matching atlas
103106
features found.*/
@@ -188,7 +191,7 @@ class CORE_EXPORT QgsAtlasComposition : public QObject
188191
// value of field that is used for ordering of features
189192
SorterKeys mFeatureKeys;
190193
// key (attribute index) used for ordering
191-
int mSortKeyAttributeIdx;
194+
QString mSortKeyAttributeName;
192195

193196
// feature filtering
194197
bool mFilterFeatures;

‎src/gui/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ qgsexpressionhighlighter.cpp
8888
qgsexpressionselectiondialog.cpp
8989
qgsextentgroupbox.cpp
9090
qgsfeatureselectiondlg.cpp
91+
qgsfieldcombobox.cpp
92+
qgsfieldmodel.cpp
9193
qgsfieldvalidator.cpp
9294
qgsfiledropedit.cpp
9395
qgsfilterlineedit.cpp
@@ -103,6 +105,9 @@ qgsmapcanvasitem.cpp
103105
qgsmapcanvasmap.cpp
104106
qgsmapcanvassnapper.cpp
105107
qgsmaplayeractionregistry.cpp
108+
qgsmaplayercombobox.cpp
109+
qgsmaplayermodel.cpp
110+
qgsmaplayerproxymodel.cpp
106111
qgsmapoverviewcanvas.cpp
107112
qgsmaptip.cpp
108113
qgsmaptool.cpp
@@ -227,6 +232,8 @@ qgsexpressionhighlighter.h
227232
qgsexpressionselectiondialog.h
228233
qgsextentgroupbox.h
229234
qgsfeatureselectiondlg.h
235+
qgsfieldcombobox.h
236+
qgsfieldmodel.h
230237
qgsfieldvalidator.h
231238
qgsfilterlineedit.h
232239
qgsformannotationitem.h
@@ -238,6 +245,9 @@ qgsludialog.h
238245
qgsmanageconnectionsdialog.h
239246
qgsmapcanvas.h
240247
qgsmaplayeractionregistry.h
248+
qgsmaplayercombobox.h
249+
qgsmaplayermodel.h
250+
qgsmaplayerproxymodel.h
241251
qgsmapoverviewcanvas.h
242252
qgsmaptool.h
243253
qgsmaptoolemitpoint.h
@@ -292,6 +302,8 @@ qgsexpressionbuilderwidget.h
292302
qgsexpressionhighlighter.h
293303
qgsexpressionselectiondialog.h
294304
qgsfeatureselectiondlg.h
305+
qgsfieldcombobox.h
306+
qgsfieldmodel.h
295307
qgsfieldvalidator.h
296308
qgsfiledropedit.h
297309
qgsfilterlineedit.h
@@ -301,6 +313,9 @@ qgsmapcanvas.h
301313
qgsmapcanvasitem.h
302314
qgsmapcanvasmap.h
303315
qgsmapcanvassnapper.h
316+
qgsmaplayercombobox.h
317+
qgsmaplayermodel.h
318+
qgsmaplayerproxymodel.h
304319
qgsmapoverviewcanvas.h
305320
qgsmaptip.h
306321
qgsmaptool.h

‎src/gui/qgsfieldcombobox.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/***************************************************************************
2+
qgsfieldcombobox.cpp
3+
--------------------------------------
4+
Date : 01.04.2014
5+
Copyright : (C) 2014 Denis Rouzaud
6+
Email : denis.rouzaud@gmail.com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgsfieldcombobox.h"
17+
#include "qgsfieldmodel.h"
18+
#include "qgsmaplayer.h"
19+
20+
QgsFieldComboBox::QgsFieldComboBox( QWidget *parent ) :
21+
QComboBox( parent )
22+
{
23+
mFieldModel = new QgsFieldModel( this );
24+
setModel( mFieldModel );
25+
26+
connect( this, SIGNAL( currentIndexChanged( int ) ), this, SLOT( indexChanged( int ) ) );
27+
}
28+
29+
void QgsFieldComboBox::setLayer( QgsMapLayer *layer )
30+
{
31+
mFieldModel->setLayer( layer );
32+
}
33+
34+
void QgsFieldComboBox::setField( QString fieldName )
35+
{
36+
QModelIndex idx = mFieldModel->indexFromName( fieldName );
37+
if ( idx.isValid() )
38+
{
39+
setCurrentIndex( idx.row() );
40+
}
41+
else
42+
{
43+
setCurrentIndex( -1 );
44+
}
45+
}
46+
47+
QString QgsFieldComboBox::currentField()
48+
{
49+
int i = currentIndex();
50+
51+
const QModelIndex index = mFieldModel->index( i, 0 );
52+
if ( !index.isValid() )
53+
{
54+
return "";
55+
}
56+
57+
QString name = mFieldModel->data( index, QgsFieldModel::FieldNameRole ).toString();
58+
return name;
59+
}
60+
61+
void QgsFieldComboBox::indexChanged( int i )
62+
{
63+
Q_UNUSED( i );
64+
QString name = currentField();
65+
emit fieldChanged( name );
66+
}

‎src/gui/qgsfieldcombobox.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/***************************************************************************
2+
qgsfieldcombobox.h
3+
--------------------------------------
4+
Date : 01.04.2014
5+
Copyright : (C) 2014 Denis Rouzaud
6+
Email : denis.rouzaud@gmail.com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSFIELDCOMBOBOX_H
17+
#define QGSFIELDCOMBOBOX_H
18+
19+
#include <QComboBox>
20+
21+
class QgsFieldModel;
22+
class QgsMapLayer;
23+
24+
/**
25+
* @brief The QgsFieldComboBox is a combo box which displays the list of fields of a given layer.
26+
* @note added in 2.3
27+
*/
28+
class GUI_EXPORT QgsFieldComboBox : public QComboBox
29+
{
30+
Q_OBJECT
31+
public:
32+
/**
33+
* @brief QgsFieldComboBox creates a combo box to display the fields of a layer.
34+
* The layer can be either manually given or dynamically set by connecting the signal QgsMapLayerComboBox::layerChanged to the slot setLayer.
35+
*/
36+
explicit QgsFieldComboBox( QWidget *parent = 0 );
37+
38+
/**
39+
* @brief currentField returns the currently selected field
40+
*/
41+
QString currentField();
42+
43+
signals:
44+
/**
45+
* @brief fieldChanged the signal is emitted when the currently selected field changes
46+
*/
47+
void fieldChanged( QString fieldName );
48+
49+
public slots:
50+
/**
51+
* @brief setLayer sets the layer of which the fields are listed
52+
*/
53+
void setLayer( QgsMapLayer* layer );
54+
/**
55+
* @brief setField sets the currently selected field
56+
*/
57+
void setField( QString fieldName );
58+
59+
protected slots:
60+
void indexChanged( int i );
61+
62+
private:
63+
QgsFieldModel* mFieldModel;
64+
65+
};
66+
67+
#endif // QGSFIELDCOMBOBOX_H

‎src/gui/qgsfieldmodel.cpp

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/***************************************************************************
2+
qgsfieldmodel.cpp
3+
--------------------------------------
4+
Date : 01.04.2014
5+
Copyright : (C) 2014 Denis Rouzaud
6+
Email : denis.rouzaud@gmail.com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgsfieldmodel.h"
17+
#include "qgsmaplayermodel.h"
18+
#include "qgsmaplayerproxymodel.h"
19+
#include "qgslogger.h"
20+
21+
22+
const int QgsFieldModel::FieldIndexRole = Qt::UserRole + 1;
23+
const int QgsFieldModel::FieldNameRole = Qt::UserRole + 2;
24+
25+
QgsFieldModel::QgsFieldModel( QObject *parent )
26+
: QAbstractItemModel( parent )
27+
, mLayer( NULL )
28+
{
29+
}
30+
31+
QModelIndex QgsFieldModel::indexFromName( QString fieldName )
32+
{
33+
int r = mFields.indexFromName( fieldName );
34+
return index( r, 0 );
35+
}
36+
37+
38+
void QgsFieldModel::setLayer( QgsMapLayer *layer )
39+
{
40+
if ( mLayer )
41+
{
42+
disconnect( mLayer, SIGNAL( updatedFields() ), this, SLOT( updateFields() ) );
43+
disconnect( mLayer, SIGNAL( layerDeleted() ), this, SLOT( layerDeleted() ) );
44+
}
45+
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( layer );
46+
if ( vl )
47+
{
48+
mLayer = vl;
49+
connect( mLayer, SIGNAL( updatedFields() ), this, SLOT( updateFields() ) );
50+
connect( mLayer, SIGNAL( layerDeleted() ), this, SLOT( layerDeleted() ) );
51+
}
52+
else
53+
{
54+
mLayer = 0;
55+
}
56+
updateFields();
57+
}
58+
59+
void QgsFieldModel::layerDeleted()
60+
{
61+
mLayer = 0;
62+
updateFields();
63+
}
64+
65+
void QgsFieldModel::updateFields()
66+
{
67+
beginResetModel();
68+
if ( mLayer )
69+
mFields = mLayer->pendingFields();
70+
else
71+
mFields = QgsFields();
72+
endResetModel();
73+
}
74+
75+
QModelIndex QgsFieldModel::index( int row, int column, const QModelIndex &parent ) const
76+
{
77+
Q_UNUSED( parent );
78+
if ( row < 0 || row >= mFields.count() )
79+
return QModelIndex();
80+
81+
return createIndex( row, column, row );
82+
}
83+
84+
QModelIndex QgsFieldModel::parent( const QModelIndex &child ) const
85+
{
86+
Q_UNUSED( child );
87+
return QModelIndex();
88+
}
89+
90+
int QgsFieldModel::rowCount( const QModelIndex &parent ) const
91+
{
92+
Q_UNUSED( parent );
93+
return mFields.count();
94+
}
95+
96+
int QgsFieldModel::columnCount( const QModelIndex &parent ) const
97+
{
98+
Q_UNUSED( parent );
99+
return 1;
100+
}
101+
102+
QVariant QgsFieldModel::data( const QModelIndex &index, int role ) const
103+
{
104+
if ( !index.isValid() )
105+
return QVariant();
106+
107+
if ( !mLayer )
108+
return QVariant();
109+
110+
if ( role == FieldNameRole )
111+
{
112+
QgsField field = mFields[index.internalId()];
113+
return field.name();
114+
}
115+
116+
if ( role == FieldIndexRole )
117+
{
118+
return index.row();
119+
}
120+
121+
if ( role == Qt::DisplayRole )
122+
{
123+
QgsField field = mFields[index.internalId()];
124+
const QMap< QString, QString > aliases = mLayer->attributeAliases();
125+
QString alias = aliases.value( field.name(), field.name() );
126+
return alias;
127+
}
128+
129+
if ( role == Qt::UserRole )
130+
{
131+
QgsField field = mFields[index.internalId()];
132+
return field.name();
133+
}
134+
135+
return QVariant();
136+
}
137+

‎src/gui/qgsfieldmodel.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/***************************************************************************
2+
qgsfieldmodel.h
3+
--------------------------------------
4+
Date : 01.04.2014
5+
Copyright : (C) 2014 Denis Rouzaud
6+
Email : denis.rouzaud@gmail.com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSFIELDMODEL_H
17+
#define QGSFIELDMODEL_H
18+
19+
#include <QAbstractItemModel>
20+
#include <QItemSelectionModel>
21+
#include <QComboBox>
22+
23+
#include "qgsvectorlayer.h"
24+
25+
/**
26+
* @brief The QgsFieldModel class is a model to display the list of fields of a layer in widgets.
27+
* It can be associated with a QgsMapLayerModel to dynamically display a layer and its fields.
28+
* @note added in 2.3
29+
*/
30+
31+
class GUI_EXPORT QgsFieldModel : public QAbstractItemModel
32+
{
33+
Q_OBJECT
34+
public:
35+
static const int FieldNameRole, FieldIndexRole;
36+
37+
/**
38+
* @brief QgsFieldModel creates a model to display the fields of a given layer
39+
*/
40+
explicit QgsFieldModel( QObject *parent = 0 );
41+
42+
/**
43+
* @brief indexFromName returns the index corresponding to a given fieldName
44+
*/
45+
QModelIndex indexFromName( QString fieldName );
46+
47+
public slots:
48+
/**
49+
* @brief setLayer sets the layer of whch fields are displayed
50+
*/
51+
void setLayer( QgsMapLayer *layer );
52+
53+
protected slots:
54+
void updateFields();
55+
void layerDeleted();
56+
57+
protected:
58+
QgsFields mFields;
59+
QgsVectorLayer* mLayer;
60+
61+
// QAbstractItemModel interface
62+
public:
63+
QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const;
64+
QModelIndex parent( const QModelIndex &child ) const;
65+
int rowCount( const QModelIndex &parent ) const;
66+
int columnCount( const QModelIndex &parent ) const;
67+
QVariant data( const QModelIndex &index, int role ) const;
68+
69+
70+
};
71+
72+
#endif // QGSFIELDMODEL_H

‎src/gui/qgsmaplayercombobox.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/***************************************************************************
2+
qgsmaplayercombobox.cpp
3+
--------------------------------------
4+
Date : 01.04.2014
5+
Copyright : (C) 2014 Denis Rouzaud
6+
Email : denis.rouzaud@gmail.com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgsmaplayercombobox.h"
17+
#include "qgsmaplayermodel.h"
18+
19+
QgsMapLayerComboBox::QgsMapLayerComboBox( QWidget *parent ) :
20+
QComboBox( parent )
21+
{
22+
mProxyModel = new QgsMapLayerProxyModel( this );
23+
setModel( mProxyModel );
24+
25+
connect( this, SIGNAL( currentIndexChanged( int ) ), this, SLOT( indexChanged( int ) ) );
26+
}
27+
28+
void QgsMapLayerComboBox::setFilters( QgsMapLayerProxyModel::Filters filters )
29+
{
30+
mProxyModel->setFilters( filters );
31+
}
32+
33+
void QgsMapLayerComboBox::setLayer( QgsMapLayer *layer )
34+
{
35+
QModelIndex idx = mProxyModel->sourceLayerModel()->indexFromLayer( layer );
36+
if ( idx.isValid() )
37+
{
38+
QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
39+
if ( proxyIdx.isValid() )
40+
{
41+
setCurrentIndex( proxyIdx.row() );
42+
return;
43+
}
44+
}
45+
setCurrentIndex( -1 );
46+
}
47+
48+
QgsMapLayer* QgsMapLayerComboBox::currentLayer()
49+
{
50+
int i = currentIndex();
51+
52+
const QModelIndex proxyIndex = mProxyModel->index( i, 0 );
53+
if ( !proxyIndex.isValid() )
54+
{
55+
return 0;
56+
}
57+
58+
const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
59+
if ( !index.isValid() )
60+
{
61+
return 0;
62+
}
63+
64+
QgsMapLayer* layer = static_cast<QgsMapLayer*>( index.internalPointer() );
65+
if ( layer )
66+
{
67+
return layer;
68+
}
69+
return 0;
70+
}
71+
72+
void QgsMapLayerComboBox::indexChanged( int i )
73+
{
74+
Q_UNUSED( i );
75+
QgsMapLayer* layer = currentLayer();
76+
emit layerChanged( layer );
77+
}
78+
79+

‎src/gui/qgsmaplayercombobox.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/***************************************************************************
2+
qgsmaplayercombobox.h
3+
--------------------------------------
4+
Date : 01.04.2014
5+
Copyright : (C) 2014 Denis Rouzaud
6+
Email : denis.rouzaud@gmail.com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSMAPLAYERCOMBOBOX_H
17+
#define QGSMAPLAYERCOMBOBOX_H
18+
19+
#include <QComboBox>
20+
21+
#include "qgsmaplayerproxymodel.h"
22+
23+
class QgsMapLayer;
24+
class QgsVectorLayer;
25+
26+
/**
27+
* @brief The QgsMapLayerComboBox class is a combo box which displays the list of layers
28+
* @note added in 2.3
29+
*/
30+
class GUI_EXPORT QgsMapLayerComboBox : public QComboBox
31+
{
32+
Q_OBJECT
33+
public:
34+
/**
35+
* @brief QgsMapLayerComboBox creates a combo box to dislpay the list of layers (currently in the registry).
36+
* The layers can be filtered and/or ordered.
37+
*/
38+
explicit QgsMapLayerComboBox( QWidget *parent = 0 );
39+
40+
/**
41+
* @brief setFilters allows fitering according to layer type and/or geometry type.
42+
*/
43+
void setFilters( QgsMapLayerProxyModel::Filters filters );
44+
45+
/**
46+
* @brief currentLayer returns the current layer selected in the combo box
47+
*/
48+
QgsMapLayer* currentLayer();
49+
50+
public slots:
51+
/**
52+
* @brief setLayer set the current layer selected in the combo
53+
*/
54+
void setLayer( QgsMapLayer* layer );
55+
56+
signals:
57+
/**
58+
* @brief layerChanged this signal is emitted whenever the currently selected layer changes
59+
*/
60+
void layerChanged( QgsMapLayer* layer );
61+
62+
protected slots:
63+
void indexChanged( int i );
64+
65+
private:
66+
QgsMapLayerProxyModel* mProxyModel;
67+
68+
};
69+
70+
#endif // QGSMAPLAYERCOMBOBOX_H

‎src/gui/qgsmaplayermodel.cpp

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
/***************************************************************************
2+
qgsmaplayermodel.cpp
3+
--------------------------------------
4+
Date : 01.04.2014
5+
Copyright : (C) 2014 Denis Rouzaud
6+
Email : denis.rouzaud@gmail.com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include <QIcon>
17+
18+
#include "qgsmaplayermodel.h"
19+
#include "qgsmaplayerregistry.h"
20+
#include "qgsapplication.h"
21+
#include "qgsvectorlayer.h"
22+
23+
24+
const int QgsMapLayerModel::LayerIdRole = Qt::UserRole + 1;
25+
26+
QgsMapLayerModel::QgsMapLayerModel( QList<QgsMapLayer *> layers, QObject *parent )
27+
: QAbstractItemModel( parent )
28+
, mLayersChecked( QMap<QString, Qt::CheckState>() )
29+
, mItemCheckable( false )
30+
{
31+
connect( QgsMapLayerRegistry::instance(), SIGNAL( removeLayers( QStringList ) ), this, SLOT( removeLayers( QStringList ) ) );
32+
addLayers( layers );
33+
}
34+
35+
QgsMapLayerModel::QgsMapLayerModel( QObject *parent )
36+
: QAbstractItemModel( parent )
37+
, mLayersChecked( QMap<QString, Qt::CheckState>() )
38+
, mItemCheckable( false )
39+
{
40+
connect( QgsMapLayerRegistry::instance(), SIGNAL( layersAdded( QList<QgsMapLayer*> ) ), this, SLOT( addLayers( QList<QgsMapLayer*> ) ) );
41+
connect( QgsMapLayerRegistry::instance(), SIGNAL( layersRemoved( QStringList ) ), this, SLOT( removeLayers( QStringList ) ) );
42+
addLayers( QgsMapLayerRegistry::instance()->mapLayers().values() );
43+
}
44+
45+
void QgsMapLayerModel::setItemsCheckable( bool checkable )
46+
{
47+
mItemCheckable = checkable;
48+
}
49+
50+
void QgsMapLayerModel::checkAll( Qt::CheckState checkState )
51+
{
52+
foreach ( const QString key, mLayersChecked.keys() )
53+
{
54+
mLayersChecked[key] = checkState;
55+
}
56+
emit dataChanged( index( 0, 0 ), index( mLayers.length() - 1, 0 ) );
57+
}
58+
59+
QList<QgsMapLayer *> QgsMapLayerModel::layersChecked( Qt::CheckState checkState )
60+
{
61+
QList<QgsMapLayer *> layers;
62+
foreach ( QgsMapLayer* layer, mLayers )
63+
{
64+
if ( mLayersChecked[layer->id()] == checkState )
65+
{
66+
layers.append( layer );
67+
}
68+
}
69+
return layers;
70+
}
71+
72+
QModelIndex QgsMapLayerModel::indexFromLayer( QgsMapLayer *layer )
73+
{
74+
int r = mLayers.indexOf( layer );
75+
return index( r, 0 );
76+
}
77+
78+
void QgsMapLayerModel::removeLayers( const QStringList layerIds )
79+
{
80+
foreach ( const QString layerId, layerIds )
81+
{
82+
QModelIndex startIndex = index( 0, 0 );
83+
QModelIndexList list = match( startIndex, LayerIdRole, layerId, 1 );
84+
if ( list.count() )
85+
{
86+
QModelIndex index = list[0];
87+
beginRemoveRows( QModelIndex(), index.row(), index.row() );
88+
mLayersChecked.remove( layerId );
89+
mLayers.removeAt( index.row() );
90+
endRemoveRows();
91+
}
92+
}
93+
}
94+
95+
void QgsMapLayerModel::addLayers( QList<QgsMapLayer *> layers )
96+
{
97+
beginInsertRows( QModelIndex(), mLayers.count(), mLayers.count() + layers.count() - 1 );
98+
foreach ( QgsMapLayer* layer, layers )
99+
{
100+
mLayers.append( layer );
101+
mLayersChecked.insert( layer->id(), Qt::Unchecked );
102+
}
103+
endInsertRows();
104+
}
105+
106+
QModelIndex QgsMapLayerModel::index( int row, int column, const QModelIndex &parent ) const
107+
{
108+
Q_UNUSED( parent );
109+
if ( row < 0 || row >= mLayers.length() )
110+
return QModelIndex();
111+
112+
return createIndex( row, column, mLayers[row] );
113+
}
114+
115+
QModelIndex QgsMapLayerModel::parent( const QModelIndex &child ) const
116+
{
117+
Q_UNUSED( child );
118+
return QModelIndex();
119+
}
120+
121+
int QgsMapLayerModel::rowCount( const QModelIndex &parent ) const
122+
{
123+
Q_UNUSED( parent );
124+
125+
return mLayers.length();
126+
}
127+
128+
int QgsMapLayerModel::columnCount( const QModelIndex &parent ) const
129+
{
130+
Q_UNUSED( parent );
131+
return 1;
132+
}
133+
134+
QVariant QgsMapLayerModel::data( const QModelIndex &index, int role ) const
135+
{
136+
if ( !index.isValid() || !index.internalPointer() )
137+
return QVariant();
138+
139+
if ( role == Qt::DisplayRole )
140+
{
141+
QgsMapLayer* layer = static_cast<QgsMapLayer*>( index.internalPointer() );
142+
return layer->name();
143+
}
144+
145+
if ( role == LayerIdRole )
146+
{
147+
QgsMapLayer* layer = static_cast<QgsMapLayer*>( index.internalPointer() );
148+
return layer->id();
149+
}
150+
151+
if ( role == Qt::CheckStateRole && mItemCheckable )
152+
{
153+
QgsMapLayer* layer = static_cast<QgsMapLayer*>( index.internalPointer() );
154+
return mLayersChecked[layer->id()];
155+
}
156+
157+
if ( role == Qt::DecorationRole )
158+
{
159+
QgsMapLayer* layer = static_cast<QgsMapLayer*>( index.internalPointer() );
160+
QgsMapLayer::LayerType type = layer->type();
161+
if ( role == Qt::DecorationRole )
162+
{
163+
switch ( type )
164+
{
165+
case QgsMapLayer::RasterLayer:
166+
{
167+
return QgsApplication::getThemeIcon( "/mIconRasterLayer.svg" );
168+
}
169+
170+
case QgsMapLayer::VectorLayer:
171+
{
172+
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( layer );
173+
if ( !vl )
174+
{
175+
return QIcon();
176+
}
177+
QGis::GeometryType geomType = vl->geometryType();
178+
switch ( geomType )
179+
{
180+
case QGis::Point:
181+
{
182+
return QgsApplication::getThemeIcon( "/mIconPointLayer.svg" );
183+
}
184+
case QGis::Polygon :
185+
{
186+
return QgsApplication::getThemeIcon( "/mIconPolygonLayer.svg" );
187+
}
188+
case QGis::Line :
189+
{
190+
return QgsApplication::getThemeIcon( "/mIconLineLayer.svg" );
191+
}
192+
case QGis::NoGeometry :
193+
{
194+
return QgsApplication::getThemeIcon( "/mIconTableLayer.png" );
195+
}
196+
default:
197+
{
198+
return QIcon();
199+
}
200+
}
201+
}
202+
default:
203+
{
204+
return QIcon();
205+
}
206+
}
207+
}
208+
}
209+
210+
return QVariant();
211+
}
212+
213+
214+
Qt::ItemFlags QgsMapLayerModel::flags( const QModelIndex &index ) const
215+
{
216+
Q_UNUSED( index );
217+
218+
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
219+
if ( mItemCheckable )
220+
{
221+
flags |= Qt::ItemIsUserCheckable;
222+
}
223+
return flags;
224+
}
225+
226+
227+
bool QgsMapLayerModel::setData( const QModelIndex &index, const QVariant &value, int role )
228+
{
229+
if ( role == Qt::CheckStateRole )
230+
{
231+
QgsMapLayer* layer = static_cast<QgsMapLayer*>( index.internalPointer() );
232+
mLayersChecked[layer->id()] = ( Qt::CheckState )value.toInt();
233+
emit dataChanged( index, index );
234+
return true;
235+
}
236+
237+
return false;
238+
}

‎src/gui/qgsmaplayermodel.h

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/***************************************************************************
2+
qgsmaplayermodel.h
3+
--------------------------------------
4+
Date : 01.04.2014
5+
Copyright : (C) 2014 Denis Rouzaud
6+
Email : denis.rouzaud@gmail.com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSMAPLAYERMODEL_H
17+
#define QGSMAPLAYERMODEL_H
18+
19+
#include <QAbstractItemModel>
20+
#include <QSortFilterProxyModel>
21+
#include <QStringList>
22+
23+
class QgsMapLayer;
24+
25+
26+
/**
27+
* @brief The QgsMapLayerModel class is a model to display layers in widgets.
28+
* @see QgsMapLayerProxyModel to sort and/filter the layers
29+
* @see QgsFieldModel to combine in with a field selector.
30+
* @note added in 2.3
31+
*/
32+
class GUI_EXPORT QgsMapLayerModel : public QAbstractItemModel
33+
{
34+
Q_OBJECT
35+
public:
36+
static const int LayerIdRole;
37+
38+
/**
39+
* @brief QgsMapLayerModel creates a model to display layers in widgets.
40+
*/
41+
explicit QgsMapLayerModel( QObject *parent = 0 );
42+
/**
43+
* @brief QgsMapLayerModel creates a model to display a specific list of layers in a widget.
44+
*/
45+
explicit QgsMapLayerModel( QList<QgsMapLayer*> layers, QObject *parent = 0 );
46+
47+
/**
48+
* @brief setItemsCheckable defines if layers should be selectable in the widget
49+
*/
50+
void setItemsCheckable( bool checkable );
51+
/**
52+
* @brief checkAll changes the checkstate for all the layers
53+
*/
54+
void checkAll( Qt::CheckState checkState );
55+
/**
56+
* @brief layersChecked returns the list of layers which are checked (or unchecked)
57+
*/
58+
QList<QgsMapLayer*> layersChecked( Qt::CheckState checkState = Qt::Checked );
59+
//! returns if the items can be checked or not
60+
bool itemsCheckable() {return mItemCheckable;}
61+
62+
/**
63+
* @brief indexFromLayer returns the model index for a given layer
64+
*/
65+
QModelIndex indexFromLayer( QgsMapLayer* layer );
66+
67+
68+
protected slots:
69+
void removeLayers( const QStringList layerIds );
70+
void addLayers( QList<QgsMapLayer*> layers );
71+
72+
protected:
73+
QList<QgsMapLayer*> mLayers;
74+
QMap<QString, Qt::CheckState> mLayersChecked;
75+
bool mItemCheckable;
76+
77+
// QAbstractItemModel interface
78+
public:
79+
QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const;
80+
QModelIndex parent( const QModelIndex &child ) const;
81+
int rowCount( const QModelIndex &parent ) const;
82+
int columnCount( const QModelIndex &parent ) const;
83+
QVariant data( const QModelIndex &index, int role ) const;
84+
bool setData( const QModelIndex &index, const QVariant &value, int role );
85+
Qt::ItemFlags flags( const QModelIndex &index ) const;
86+
};
87+
88+
#endif // QGSMAPLAYERMODEL_H

‎src/gui/qgsmaplayerproxymodel.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/***************************************************************************
2+
qgsmaplayerproxymodel.cpp
3+
--------------------------------------
4+
Date : 01.04.2014
5+
Copyright : (C) 2014 Denis Rouzaud
6+
Email : denis.rouzaud@gmail.com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgsmaplayerproxymodel.h"
17+
#include "qgsmaplayermodel.h"
18+
#include "qgsmaplayer.h"
19+
#include "qgsvectorlayer.h"
20+
21+
QgsMapLayerProxyModel::QgsMapLayerProxyModel( QObject *parent )
22+
: QSortFilterProxyModel( parent )
23+
, mFilters( NoFilter )
24+
, mModel( new QgsMapLayerModel( this ) )
25+
{
26+
setSourceModel( mModel );
27+
}
28+
29+
QgsMapLayerProxyModel *QgsMapLayerProxyModel::setFilters( Filters filters )
30+
{
31+
mFilters = filters;
32+
return this;
33+
}
34+
35+
bool QgsMapLayerProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
36+
{
37+
if ( mFilters.testFlag( NoFilter ) )
38+
return true;
39+
40+
QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
41+
QgsMapLayer* layer = static_cast<QgsMapLayer*>( index.internalPointer() );
42+
if ( !layer )
43+
return false;
44+
45+
// layer type
46+
if (( mFilters.testFlag( RasterLayer ) && layer->type() == QgsMapLayer::RasterLayer ) ||
47+
( mFilters.testFlag( VectorLayer ) && layer->type() == QgsMapLayer::VectorLayer ) )
48+
return true;
49+
50+
// geometry type
51+
bool detectGeometry = mFilters.testFlag( NoGeometry ) ||
52+
mFilters.testFlag( PointLayer ) ||
53+
mFilters.testFlag( LineLayer ) ||
54+
mFilters.testFlag( PolygonLayer ) ||
55+
mFilters.testFlag( HasGeometry );
56+
if ( detectGeometry && layer->type() == QgsMapLayer::VectorLayer )
57+
{
58+
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( layer );
59+
if ( vl )
60+
{
61+
if ( mFilters.testFlag( HasGeometry ) && vl->hasGeometryType() )
62+
return true;
63+
if ( mFilters.testFlag( NoGeometry ) && vl->geometryType() == QGis::NoGeometry )
64+
return true;
65+
if ( mFilters.testFlag( PointLayer ) && vl->geometryType() == QGis::Point )
66+
return true;
67+
if ( mFilters.testFlag( LineLayer ) && vl->geometryType() == QGis::Line )
68+
return true;
69+
if ( mFilters.testFlag( PolygonLayer ) && vl->geometryType() == QGis::Polygon )
70+
return true;
71+
}
72+
}
73+
74+
return false;
75+
}
76+
77+
bool QgsMapLayerProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
78+
{
79+
// default mode is alphabetical order
80+
QString leftId = sourceModel()->data( left ).toString();
81+
QString rightId = sourceModel()->data( right ).toString();
82+
return QString::localeAwareCompare( leftId, rightId ) < 0;
83+
}

‎src/gui/qgsmaplayerproxymodel.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/***************************************************************************
2+
qgsmaplayerproxymodel.h
3+
--------------------------------------
4+
Date : 01.04.2014
5+
Copyright : (C) 2014 Denis Rouzaud
6+
Email : denis.rouzaud@gmail.com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSMAPLAYERPROXYMODEL_H
17+
#define QGSMAPLAYERPROXYMODEL_H
18+
19+
#include <QSortFilterProxyModel>
20+
21+
class QgsMapLayerModel;
22+
23+
/**
24+
* @brief The QgsMapLayerProxModel class provides an easy to use model to display the list of layers in widgets.
25+
* @note added in 2.3
26+
*/
27+
class GUI_EXPORT QgsMapLayerProxyModel : public QSortFilterProxyModel
28+
{
29+
Q_OBJECT
30+
public:
31+
enum Filter
32+
{
33+
NoFilter = 1,
34+
RasterLayer = 2,
35+
NoGeometry = 4,
36+
PointLayer = 8,
37+
LineLayer = 16,
38+
PolygonLayer = 32,
39+
HasGeometry = PointLayer | LineLayer | PolygonLayer,
40+
VectorLayer = NoGeometry | HasGeometry
41+
};
42+
Q_DECLARE_FLAGS( Filters, Filter )
43+
44+
/**
45+
* @brief QgsMapLayerProxModel creates a proxy model with a QgsMapLayerModel as source model.
46+
* It can be used to filter the layers list in a widget.
47+
*/
48+
explicit QgsMapLayerProxyModel( QObject *parent = 0 );
49+
50+
/**
51+
* @brief layerModel returns the QgsMapLayerModel used in this QSortFilterProxyModel
52+
*/
53+
QgsMapLayerModel* sourceLayerModel() {return mModel;}
54+
55+
/**
56+
* @brief setFilters set flags that affect how layers are filtered
57+
* @param filters are Filter flags
58+
* @note added in 2.3
59+
*/
60+
QgsMapLayerProxyModel* setFilters( Filters filters );
61+
const Filters& filters() const { return mFilters; }
62+
63+
private:
64+
Filters mFilters;
65+
QgsMapLayerModel* mModel;
66+
67+
// QSortFilterProxyModel interface
68+
public:
69+
bool filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const;
70+
bool lessThan( const QModelIndex &left, const QModelIndex &right ) const;
71+
};
72+
73+
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsMapLayerProxyModel::Filters )
74+
75+
#endif // QGSMAPLAYERPROXYMODEL_H

‎src/ui/qgsatlascompositionwidgetbase.ui

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@
131131
</widget>
132132
</item>
133133
<item row="0" column="2">
134-
<widget class="QComboBox" name="mAtlasCoverageLayerComboBox">
134+
<widget class="QgsMapLayerComboBox" name="mAtlasCoverageLayerComboBox">
135135
<property name="sizePolicy">
136136
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
137137
<horstretch>0</horstretch>
@@ -206,7 +206,7 @@
206206
</widget>
207207
</item>
208208
<item row="3" column="1">
209-
<widget class="QComboBox" name="mAtlasSortFeatureKeyComboBox"/>
209+
<widget class="QgsFieldComboBox" name="mAtlasSortFeatureKeyComboBox"/>
210210
</item>
211211
<item row="3" column="0">
212212
<widget class="QCheckBox" name="mAtlasSortFeatureCheckBox">
@@ -284,9 +284,19 @@
284284
<customwidget>
285285
<class>QgsCollapsibleGroupBoxBasic</class>
286286
<extends>QGroupBox</extends>
287-
<header location="global">qgscollapsiblegroupbox.h</header>
287+
<header>qgscollapsiblegroupbox.h</header>
288288
<container>1</container>
289289
</customwidget>
290+
<customwidget>
291+
<class>QgsMapLayerComboBox</class>
292+
<extends>QComboBox</extends>
293+
<header location="global">qgsmaplayercombobox.h</header>
294+
</customwidget>
295+
<customwidget>
296+
<class>QgsFieldComboBox</class>
297+
<extends>QComboBox</extends>
298+
<header location="global">qgsfieldcombobox.h</header>
299+
</customwidget>
290300
</customwidgets>
291301
<resources>
292302
<include location="../../images/images.qrc"/>

‎src/ui/qgsdxfexportdialogbase.ui

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>377</width>
10-
<height>292</height>
9+
<width>406</width>
10+
<height>293</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
@@ -80,7 +80,11 @@
8080
<widget class="QLineEdit" name="mSymbologyScaleLineEdit"/>
8181
</item>
8282
<item row="3" column="0" colspan="3">
83-
<widget class="QListWidget" name="mLayersListWidget"/>
83+
<widget class="QListView" name="mLayersListView">
84+
<property name="selectionMode">
85+
<enum>QAbstractItemView::NoSelection</enum>
86+
</property>
87+
</widget>
8488
</item>
8589
</layout>
8690
</item>

‎tests/src/core/testqgsatlascomposition.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ void TestQgsAtlasComposition::sorting_render()
330330
mAtlas->setHideCoverage( false );
331331

332332
mAtlas->setSortFeatures( true );
333-
mAtlas->setSortKeyAttributeIndex( 4 ); // departement name
333+
mAtlas->setSortKeyAttributeName( "NAME_1" ); // departement name
334334
mAtlas->setSortAscending( false );
335335

336336
mAtlas->beginRender();

0 commit comments

Comments
 (0)
Please sign in to comment.