QGIS API Documentation  3.13.0-Master (740be229cb)
qgsmaplayercombobox.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmaplayercombobox.cpp
3  --------------------------------------
4  Date : 01.04.2014
5  Copyright : (C) 2014 Denis Rouzaud
6  Email : [email protected]
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 #include "qgsmimedatautils.h"
19 #include <QDragEnterEvent>
20 #include <QPainter>
21 
23  : QComboBox( parent )
24 {
25  mProxyModel = new QgsMapLayerProxyModel( this );
26  setModel( mProxyModel );
27 
28  connect( this, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::activated ), this, &QgsMapLayerComboBox::indexChanged );
29  connect( mProxyModel, &QAbstractItemModel::rowsInserted, this, &QgsMapLayerComboBox::rowsChanged );
30  connect( mProxyModel, &QAbstractItemModel::rowsRemoved, this, &QgsMapLayerComboBox::rowsChanged );
31 
32  setSizeAdjustPolicy( QComboBox::AdjustToMinimumContentsLengthWithIcon );
33 
34  setAcceptDrops( true );
35 }
36 
37 void QgsMapLayerComboBox::setExcludedProviders( const QStringList &providers )
38 {
39  mProxyModel->setExcludedProviders( providers );
40 }
41 
43 {
44  return mProxyModel->excludedProviders();
45 }
46 
48 {
49  mProxyModel->sourceLayerModel()->setAllowEmptyLayer( allowEmpty );
50 }
51 
53 {
54  return mProxyModel->sourceLayerModel()->allowEmptyLayer();
55 }
56 
58 {
59  mProxyModel->sourceLayerModel()->setShowCrs( showCrs );
60 }
61 
63 {
64  return mProxyModel->sourceLayerModel()->showCrs();
65 }
66 
67 void QgsMapLayerComboBox::setAdditionalItems( const QStringList &items )
68 {
69  mProxyModel->sourceLayerModel()->setAdditionalItems( items );
70 }
71 
73 {
74  return mProxyModel->sourceLayerModel()->additionalItems();
75 }
76 
78 {
79  if ( layer == currentLayer() && ( layer || !isEditable() || currentText().isEmpty() ) )
80  return;
81 
82  if ( !layer )
83  {
84  setCurrentIndex( -1 );
85  emit layerChanged( nullptr );
86  return;
87  }
88 
89  QModelIndex idx = mProxyModel->sourceLayerModel()->indexFromLayer( layer );
90  if ( idx.isValid() )
91  {
92  QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
93  if ( proxyIdx.isValid() )
94  {
95  setCurrentIndex( proxyIdx.row() );
96  emit layerChanged( currentLayer() );
97  return;
98  }
99  }
100  setCurrentIndex( -1 );
101  emit layerChanged( currentLayer() );
102 }
103 
105 {
106  return layer( currentIndex() );
107 }
108 
109 QgsMapLayer *QgsMapLayerComboBox::layer( int layerIndex ) const
110 {
111  const QModelIndex proxyIndex = mProxyModel->index( layerIndex, 0 );
112  if ( !proxyIndex.isValid() )
113  {
114  return nullptr;
115  }
116 
117  const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
118  if ( !index.isValid() )
119  {
120  return nullptr;
121  }
122 
123  QgsMapLayer *layer = static_cast<QgsMapLayer *>( index.internalPointer() );
124  if ( layer )
125  {
126  return layer;
127  }
128  return nullptr;
129 }
130 
132 {
133  Q_UNUSED( i )
135  emit layerChanged( layer );
136 }
137 
139 {
140  if ( count() == 1 )
141  {
142  //currently selected layer item has changed
143  emit layerChanged( currentLayer() );
144  }
145  else if ( count() == 0 )
146  {
147  emit layerChanged( nullptr );
148  }
149 }
150 
151 QgsMapLayer *QgsMapLayerComboBox::compatibleMapLayerFromMimeData( const QMimeData *data ) const
152 {
154  for ( const QgsMimeDataUtils::Uri &u : uriList )
155  {
156  // is this uri from the current project?
157  if ( QgsMapLayer *layer = u.mapLayer() )
158  {
159  if ( mProxyModel->acceptsLayer( layer ) )
160  return layer;
161  }
162  }
163  return nullptr;
164 }
165 
166 void QgsMapLayerComboBox::dragEnterEvent( QDragEnterEvent *event )
167 {
168  if ( !( event->possibleActions() & Qt::CopyAction ) )
169  {
170  event->ignore();
171  return;
172  }
173 
174  if ( compatibleMapLayerFromMimeData( event->mimeData() ) )
175  {
176  // dragged an acceptable layer, phew
177  event->setDropAction( Qt::CopyAction );
178  event->accept();
179  mDragActive = true;
180  update();
181  }
182  else
183  {
184  event->ignore();
185  }
186 }
187 
188 void QgsMapLayerComboBox::dragLeaveEvent( QDragLeaveEvent *event )
189 {
190  if ( mDragActive )
191  {
192  event->accept();
193  mDragActive = false;
194  update();
195  }
196  else
197  {
198  event->ignore();
199  }
200 }
201 
202 void QgsMapLayerComboBox::dropEvent( QDropEvent *event )
203 {
204  if ( !( event->possibleActions() & Qt::CopyAction ) )
205  {
206  event->ignore();
207  return;
208  }
209 
210  if ( QgsMapLayer *layer = compatibleMapLayerFromMimeData( event->mimeData() ) )
211  {
212  // dropped an acceptable layer, phew
213  setFocus( Qt::MouseFocusReason );
214  event->setDropAction( Qt::CopyAction );
215  event->accept();
216 
217  setLayer( layer );
218  }
219  else
220  {
221  event->ignore();
222  }
223  mDragActive = false;
224  update();
225 }
226 
227 void QgsMapLayerComboBox::paintEvent( QPaintEvent *e )
228 {
229  QComboBox::paintEvent( e );
230  if ( mDragActive || mHighlight )
231  {
232  QPainter p( this );
233  int width = 2; // width of highlight rectangle inside frame
234  p.setPen( QPen( palette().highlight(), width ) );
235  QRect r = rect().adjusted( width, width, -width, -width );
236  p.drawRect( r );
237  }
238 }
QStringList excludedProviders() const
Returns the list of data providers which are excluded from the combobox.
QModelIndex indexFromLayer(QgsMapLayer *layer) const
indexFromLayer returns the model index for a given layer
Base class for all map layer types.
Definition: qgsmaplayer.h:80
QStringList additionalItems
bool allowEmptyLayer() const
Returns true if the combo box allows the empty layer ("not set") choice.
void setExcludedProviders(const QStringList &providers)
Sets a list of data providers which should be excluded from the combobox.
static UriList decodeUriList(const QMimeData *data)
void dragEnterEvent(QDragEnterEvent *event) override
QStringList excludedProviders() const
Returns the blacklist of data providers which are excluded from the model.
void layerChanged(QgsMapLayer *layer)
Emitted whenever the currently selected layer changes.
void setAdditionalItems(const QStringList &items)
Sets a list of additional (non map layer) items to include at the end of the combobox.
bool acceptsLayer(QgsMapLayer *layer) const
Returns true if the proxy model accepts the specified map layer.
void setShowCrs(bool showCrs)
Sets whether the CRS of layers is also included in the model&#39;s display role.
QStringList additionalItems() const
Returns the list of additional (non map layer) items included at the end of the combo box...
The QgsMapLayerProxyModel class provides an easy to use model to display the list of layers in widget...
QgsMapLayerModel * sourceLayerModel() const
layerModel returns the QgsMapLayerModel used in this QSortFilterProxyModel
void setAllowEmptyLayer(bool allowEmpty)
Sets whether an optional empty layer ("not set") option is present in the model.
QgsMapLayerComboBox(QWidget *parent=nullptr)
QgsMapLayerComboBox creates a combo box to display the list of layers (currently in the registry)...
void setAllowEmptyLayer(bool allowEmpty)
Sets whether an optional empty layer ("not set") option is shown in the combo box.
void setShowCrs(bool showCrs)
Sets whether the CRS of layers is also included in the combo box text.
void paintEvent(QPaintEvent *e) override
void setLayer(QgsMapLayer *layer)
setLayer set the current layer selected in the combo
bool showCrs() const
Returns true if the combo box shows the layer&#39;s CRS.
void setExcludedProviders(const QStringList &providers)
Sets a blacklist of data providers which should be excluded from the model.
QList< QgsMimeDataUtils::Uri > UriList
void setAdditionalItems(const QStringList &items)
Sets a list of additional (non map layer) items to include at the end of the model.
void dragLeaveEvent(QDragLeaveEvent *event) override
void dropEvent(QDropEvent *event) override
QgsMapLayer * layer(int layerIndex) const
Returns the layer currently shown at the specified index within the combo box.
QgsMapLayer * currentLayer() const
Returns the current layer selected in the combo box.