QGIS API Documentation  3.9.0-Master (cebdc8dded)
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  setAcceptDrops( true );
33 }
34 
35 void QgsMapLayerComboBox::setExcludedProviders( const QStringList &providers )
36 {
37  mProxyModel->setExcludedProviders( providers );
38 }
39 
41 {
42  return mProxyModel->excludedProviders();
43 }
44 
46 {
47  mProxyModel->sourceLayerModel()->setAllowEmptyLayer( allowEmpty );
48 }
49 
51 {
52  return mProxyModel->sourceLayerModel()->allowEmptyLayer();
53 }
54 
56 {
57  mProxyModel->sourceLayerModel()->setShowCrs( showCrs );
58 }
59 
61 {
62  return mProxyModel->sourceLayerModel()->showCrs();
63 }
64 
65 void QgsMapLayerComboBox::setAdditionalItems( const QStringList &items )
66 {
67  mProxyModel->sourceLayerModel()->setAdditionalItems( items );
68 }
69 
71 {
72  return mProxyModel->sourceLayerModel()->additionalItems();
73 }
74 
76 {
77  if ( layer == currentLayer() )
78  return;
79 
80  if ( !layer )
81  {
82  setCurrentIndex( -1 );
83  emit layerChanged( nullptr );
84  return;
85  }
86 
87  QModelIndex idx = mProxyModel->sourceLayerModel()->indexFromLayer( layer );
88  if ( idx.isValid() )
89  {
90  QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
91  if ( proxyIdx.isValid() )
92  {
93  setCurrentIndex( proxyIdx.row() );
94  emit layerChanged( currentLayer() );
95  return;
96  }
97  }
98  setCurrentIndex( -1 );
99  emit layerChanged( currentLayer() );
100 }
101 
103 {
104  return layer( currentIndex() );
105 }
106 
107 QgsMapLayer *QgsMapLayerComboBox::layer( int layerIndex ) const
108 {
109  const QModelIndex proxyIndex = mProxyModel->index( layerIndex, 0 );
110  if ( !proxyIndex.isValid() )
111  {
112  return nullptr;
113  }
114 
115  const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
116  if ( !index.isValid() )
117  {
118  return nullptr;
119  }
120 
121  QgsMapLayer *layer = static_cast<QgsMapLayer *>( index.internalPointer() );
122  if ( layer )
123  {
124  return layer;
125  }
126  return nullptr;
127 }
128 
130 {
131  Q_UNUSED( i )
133  emit layerChanged( layer );
134 }
135 
137 {
138  if ( count() == 1 )
139  {
140  //currently selected layer item has changed
141  emit layerChanged( currentLayer() );
142  }
143  else if ( count() == 0 )
144  {
145  emit layerChanged( nullptr );
146  }
147 }
148 
149 QgsMapLayer *QgsMapLayerComboBox::compatibleMapLayerFromMimeData( const QMimeData *data ) const
150 {
152  for ( const QgsMimeDataUtils::Uri &u : uriList )
153  {
154  // is this uri from the current project?
155  if ( QgsMapLayer *layer = u.mapLayer() )
156  {
157  if ( mProxyModel->acceptsLayer( layer ) )
158  return layer;
159  }
160  }
161  return nullptr;
162 }
163 
164 void QgsMapLayerComboBox::dragEnterEvent( QDragEnterEvent *event )
165 {
166  if ( !( event->possibleActions() & Qt::CopyAction ) )
167  {
168  event->ignore();
169  return;
170  }
171 
172  if ( compatibleMapLayerFromMimeData( event->mimeData() ) )
173  {
174  // dragged an acceptable layer, phew
175  event->setDropAction( Qt::CopyAction );
176  event->accept();
177  mDragActive = true;
178  update();
179  }
180  else
181  {
182  event->ignore();
183  }
184 }
185 
186 void QgsMapLayerComboBox::dragLeaveEvent( QDragLeaveEvent *event )
187 {
188  if ( mDragActive )
189  {
190  event->accept();
191  mDragActive = false;
192  update();
193  }
194  else
195  {
196  event->ignore();
197  }
198 }
199 
200 void QgsMapLayerComboBox::dropEvent( QDropEvent *event )
201 {
202  if ( !( event->possibleActions() & Qt::CopyAction ) )
203  {
204  event->ignore();
205  return;
206  }
207 
208  if ( QgsMapLayer *layer = compatibleMapLayerFromMimeData( event->mimeData() ) )
209  {
210  // dropped an acceptable layer, phew
211  setFocus( Qt::MouseFocusReason );
212  event->setDropAction( Qt::CopyAction );
213  event->accept();
214 
215  setLayer( layer );
216  }
217  else
218  {
219  event->ignore();
220  }
221  mDragActive = false;
222  update();
223 }
224 
225 void QgsMapLayerComboBox::paintEvent( QPaintEvent *e )
226 {
227  QComboBox::paintEvent( e );
228  if ( mDragActive || mHighlight )
229  {
230  QPainter p( this );
231  int width = 2; // width of highlight rectangle inside frame
232  p.setPen( QPen( palette().highlight(), width ) );
233  QRect r = rect().adjusted( width, width, -width, -width );
234  p.drawRect( r );
235  }
236 }
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:79
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.