QGIS API Documentation  3.25.0-Master (10b47c2603)
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 : denis.rouzaud[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  mProxyModel->setProject( project );
45 }
46 
47 
49 {
50  return mProxyModel->excludedProviders();
51 }
52 
53 void QgsMapLayerComboBox::setAllowEmptyLayer( bool allowEmpty, const QString &text, const QIcon &icon )
54 {
55  mProxyModel->sourceLayerModel()->setAllowEmptyLayer( allowEmpty, text, icon );
56 }
57 
59 {
60  return mProxyModel->sourceLayerModel()->allowEmptyLayer();
61 }
62 
63 void QgsMapLayerComboBox::setShowCrs( bool showCrs )
64 {
65  mProxyModel->sourceLayerModel()->setShowCrs( showCrs );
66 }
67 
69 {
70  return mProxyModel->sourceLayerModel()->showCrs();
71 }
72 
73 void QgsMapLayerComboBox::setAdditionalItems( const QStringList &items )
74 {
75  mProxyModel->sourceLayerModel()->setAdditionalItems( items );
76 }
77 
79 {
80  return mProxyModel->sourceLayerModel()->additionalItems();
81 }
82 
83 void QgsMapLayerComboBox::setAdditionalLayers( const QList<QgsMapLayer *> &layers )
84 {
85  mProxyModel->sourceLayerModel()->setAdditionalLayers( layers );
86 }
87 
88 QList<QgsMapLayer *> QgsMapLayerComboBox::additionalLayers() const
89 {
90  return mProxyModel->sourceLayerModel()->additionalLayers();
91 }
92 
94 {
95  if ( layer == currentLayer() && ( layer || !isEditable() || currentText().isEmpty() ) )
96  return;
97 
98  if ( !layer )
99  {
100  setCurrentIndex( -1 );
101  emit layerChanged( nullptr );
102  return;
103  }
104 
105  const QModelIndex idx = mProxyModel->sourceLayerModel()->indexFromLayer( layer );
106  if ( idx.isValid() )
107  {
108  const QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
109  if ( proxyIdx.isValid() )
110  {
111  setCurrentIndex( proxyIdx.row() );
112  emit layerChanged( currentLayer() );
113  return;
114  }
115  }
116  setCurrentIndex( -1 );
117  emit layerChanged( currentLayer() );
118 }
119 
121 {
122  return layer( currentIndex() );
123 }
124 
125 QgsMapLayer *QgsMapLayerComboBox::layer( int layerIndex ) const
126 {
127  const QModelIndex proxyIndex = mProxyModel->index( layerIndex, 0 );
128  if ( !proxyIndex.isValid() )
129  {
130  return nullptr;
131  }
132 
133  const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
134  if ( !index.isValid() )
135  {
136  return nullptr;
137  }
138 
139  QgsMapLayer *layer = static_cast<QgsMapLayer *>( index.internalPointer() );
140  if ( layer )
141  {
142  return layer;
143  }
144  return nullptr;
145 }
146 
148 {
149  Q_UNUSED( i )
151  emit layerChanged( layer );
152 }
153 
155 {
156  if ( count() == 1 )
157  {
158  //currently selected layer item has changed
159  emit layerChanged( currentLayer() );
160  }
161  else if ( count() == 0 )
162  {
163  emit layerChanged( nullptr );
164  }
165 }
166 
167 QgsMapLayer *QgsMapLayerComboBox::compatibleMapLayerFromMimeData( const QMimeData *data ) const
168 {
170  for ( const QgsMimeDataUtils::Uri &u : uriList )
171  {
172  // is this uri from the current project?
173  if ( QgsMapLayer *layer = u.mapLayer() )
174  {
175  if ( mProxyModel->acceptsLayer( layer ) )
176  return layer;
177  }
178  }
179  return nullptr;
180 }
181 
182 void QgsMapLayerComboBox::dragEnterEvent( QDragEnterEvent *event )
183 {
184  if ( !( event->possibleActions() & Qt::CopyAction ) )
185  {
186  event->ignore();
187  return;
188  }
189 
190  if ( compatibleMapLayerFromMimeData( event->mimeData() ) )
191  {
192  // dragged an acceptable layer, phew
193  event->setDropAction( Qt::CopyAction );
194  event->accept();
195  mDragActive = true;
196  update();
197  }
198  else
199  {
200  event->ignore();
201  }
202 }
203 
204 void QgsMapLayerComboBox::dragLeaveEvent( QDragLeaveEvent *event )
205 {
206  if ( mDragActive )
207  {
208  event->accept();
209  mDragActive = false;
210  update();
211  }
212  else
213  {
214  event->ignore();
215  }
216 }
217 
218 void QgsMapLayerComboBox::dropEvent( QDropEvent *event )
219 {
220  if ( !( event->possibleActions() & Qt::CopyAction ) )
221  {
222  event->ignore();
223  return;
224  }
225 
226  if ( QgsMapLayer *layer = compatibleMapLayerFromMimeData( event->mimeData() ) )
227  {
228  // dropped an acceptable layer, phew
229  setFocus( Qt::MouseFocusReason );
230  event->setDropAction( Qt::CopyAction );
231  event->accept();
232 
233  setLayer( layer );
234  }
235  else
236  {
237  event->ignore();
238  }
239  mDragActive = false;
240  update();
241 }
242 
243 void QgsMapLayerComboBox::paintEvent( QPaintEvent *e )
244 {
245  QComboBox::paintEvent( e );
246  if ( mDragActive || mHighlight )
247  {
248  QPainter p( this );
249  const int width = 2; // width of highlight rectangle inside frame
250  p.setPen( QPen( palette().highlight(), width ) );
251  const QRect r = rect().adjusted( width, width, -width, -width );
252  p.drawRect( r );
253  }
254 }
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 setProject(QgsProject *project)
Sets the project from which map layers are shown.
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.
void setProject(QgsProject *project)
Sets the project from which map layers are shown.
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)
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:104