QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
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 
47 void QgsMapLayerComboBox::setAllowEmptyLayer( bool allowEmpty, const QString &text, const QIcon &icon )
48 {
49  mProxyModel->sourceLayerModel()->setAllowEmptyLayer( allowEmpty, text, icon );
50 }
51 
53 {
54  return mProxyModel->sourceLayerModel()->allowEmptyLayer();
55 }
56 
57 void QgsMapLayerComboBox::setShowCrs( bool showCrs )
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 
77 void QgsMapLayerComboBox::setAdditionalLayers( const QList<QgsMapLayer *> &layers )
78 {
79  mProxyModel->sourceLayerModel()->setAdditionalLayers( layers );
80 }
81 
82 QList<QgsMapLayer *> QgsMapLayerComboBox::additionalLayers() const
83 {
84  return mProxyModel->sourceLayerModel()->additionalLayers();
85 }
86 
88 {
89  if ( layer == currentLayer() && ( layer || !isEditable() || currentText().isEmpty() ) )
90  return;
91 
92  if ( !layer )
93  {
94  setCurrentIndex( -1 );
95  emit layerChanged( nullptr );
96  return;
97  }
98 
99  const QModelIndex idx = mProxyModel->sourceLayerModel()->indexFromLayer( layer );
100  if ( idx.isValid() )
101  {
102  const QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
103  if ( proxyIdx.isValid() )
104  {
105  setCurrentIndex( proxyIdx.row() );
106  emit layerChanged( currentLayer() );
107  return;
108  }
109  }
110  setCurrentIndex( -1 );
111  emit layerChanged( currentLayer() );
112 }
113 
115 {
116  return layer( currentIndex() );
117 }
118 
119 QgsMapLayer *QgsMapLayerComboBox::layer( int layerIndex ) const
120 {
121  const QModelIndex proxyIndex = mProxyModel->index( layerIndex, 0 );
122  if ( !proxyIndex.isValid() )
123  {
124  return nullptr;
125  }
126 
127  const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
128  if ( !index.isValid() )
129  {
130  return nullptr;
131  }
132 
133  QgsMapLayer *layer = static_cast<QgsMapLayer *>( index.internalPointer() );
134  if ( layer )
135  {
136  return layer;
137  }
138  return nullptr;
139 }
140 
142 {
143  Q_UNUSED( i )
145  emit layerChanged( layer );
146 }
147 
149 {
150  if ( count() == 1 )
151  {
152  //currently selected layer item has changed
153  emit layerChanged( currentLayer() );
154  }
155  else if ( count() == 0 )
156  {
157  emit layerChanged( nullptr );
158  }
159 }
160 
161 QgsMapLayer *QgsMapLayerComboBox::compatibleMapLayerFromMimeData( const QMimeData *data ) const
162 {
164  for ( const QgsMimeDataUtils::Uri &u : uriList )
165  {
166  // is this uri from the current project?
167  if ( QgsMapLayer *layer = u.mapLayer() )
168  {
169  if ( mProxyModel->acceptsLayer( layer ) )
170  return layer;
171  }
172  }
173  return nullptr;
174 }
175 
176 void QgsMapLayerComboBox::dragEnterEvent( QDragEnterEvent *event )
177 {
178  if ( !( event->possibleActions() & Qt::CopyAction ) )
179  {
180  event->ignore();
181  return;
182  }
183 
184  if ( compatibleMapLayerFromMimeData( event->mimeData() ) )
185  {
186  // dragged an acceptable layer, phew
187  event->setDropAction( Qt::CopyAction );
188  event->accept();
189  mDragActive = true;
190  update();
191  }
192  else
193  {
194  event->ignore();
195  }
196 }
197 
198 void QgsMapLayerComboBox::dragLeaveEvent( QDragLeaveEvent *event )
199 {
200  if ( mDragActive )
201  {
202  event->accept();
203  mDragActive = false;
204  update();
205  }
206  else
207  {
208  event->ignore();
209  }
210 }
211 
212 void QgsMapLayerComboBox::dropEvent( QDropEvent *event )
213 {
214  if ( !( event->possibleActions() & Qt::CopyAction ) )
215  {
216  event->ignore();
217  return;
218  }
219 
220  if ( QgsMapLayer *layer = compatibleMapLayerFromMimeData( event->mimeData() ) )
221  {
222  // dropped an acceptable layer, phew
223  setFocus( Qt::MouseFocusReason );
224  event->setDropAction( Qt::CopyAction );
225  event->accept();
226 
227  setLayer( layer );
228  }
229  else
230  {
231  event->ignore();
232  }
233  mDragActive = false;
234  update();
235 }
236 
237 void QgsMapLayerComboBox::paintEvent( QPaintEvent *e )
238 {
239  QComboBox::paintEvent( e );
240  if ( mDragActive || mHighlight )
241  {
242  QPainter p( this );
243  const int width = 2; // width of highlight rectangle inside frame
244  p.setPen( QPen( palette().highlight(), width ) );
245  const QRect r = rect().adjusted( width, width, -width, -width );
246  p.drawRect( r );
247  }
248 }
void dragLeaveEvent(QDragLeaveEvent *event) override
QStringList additionalItems() const
Returns the list of additional (non map layer) items included at the end of the combo box.
void setAdditionalLayers(const QList< QgsMapLayer * > &layers)
Sets a list of additional layers to include in the combobox.
QgsMapLayerComboBox(QWidget *parent=nullptr)
QgsMapLayerComboBox creates a combo box to display the list of layers (currently in the registry).
void paintEvent(QPaintEvent *e) override
void setLayer(QgsMapLayer *layer)
setLayer set the current layer selected in the combo
void setExcludedProviders(const QStringList &providers)
Sets a list of data providers which should be excluded from the combobox.
void dropEvent(QDropEvent *event) override
QgsMapLayer * layer(int layerIndex) const
Returns the layer currently shown at the specified index within the combo box.
void setShowCrs(bool showCrs)
Sets whether the CRS of layers is also included in the combo box text.
void setAllowEmptyLayer(bool allowEmpty, const QString &text=QString(), const QIcon &icon=QIcon())
Sets whether an optional empty layer ("not set") option is shown in the combo box.
void setAdditionalItems(const QStringList &items)
Sets a list of additional (non map layer) items to include at the end of the combobox.
void layerChanged(QgsMapLayer *layer)
Emitted whenever the currently selected layer changes.
QList< QgsMapLayer * > additionalLayers() const
Returns the list of additional layers added to the combobox.
void dragEnterEvent(QDragEnterEvent *event) override
QgsMapLayer * currentLayer() const
Returns the current layer selected in the combo box.
void setShowCrs(bool showCrs)
Sets whether the CRS of layers is also included in the model's display role.
QModelIndex indexFromLayer(QgsMapLayer *layer) const
indexFromLayer returns the model index for a given layer
void setAllowEmptyLayer(bool allowEmpty, const QString &text=QString(), const QIcon &icon=QIcon())
Sets whether an optional empty layer ("not set") option is present in the model.
void setAdditionalItems(const QStringList &items)
Sets a list of additional (non map layer) items to include at the end of the model.
QList< QgsMapLayer * > additionalLayers() const
Returns the list of additional layers added to the model.
QStringList additionalItems
void setAdditionalLayers(const QList< QgsMapLayer * > &layers)
Sets a list of additional layers to include in the model.
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
bool acceptsLayer(QgsMapLayer *layer) const
Returns true if the proxy model accepts the specified map layer.
void setExcludedProviders(const QStringList &providers)
Sets a blocklist of data providers which should be excluded from the model.
QStringList excludedProviders() const
Returns the blocklist of data providers which are excluded from the model.
Base class for all map layer types.
Definition: qgsmaplayer.h:73
QList< QgsMimeDataUtils::Uri > UriList
static UriList decodeUriList(const QMimeData *data)