QGIS API Documentation  3.25.0-Master (dec16ba68b)
qgsdataitem.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsdataitem.cpp - Data items
3  -------------------
4  begin : 2011-04-01
5  copyright : (C) 2011 Radim Blazek
6  email : radim dot blazek at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgis.h"
19 #include "qgsdataitem.h"
20 #include "qgsapplication.h"
21 #include "qgsdataitemprovider.h"
23 #include "qgsdataprovider.h"
24 #include "qgslogger.h"
25 #include "qgsproviderregistry.h"
26 #include "qgsconfig.h"
27 #include "qgssettings.h"
28 #include "qgsanimatedicon.h"
29 #include "qgsproject.h"
30 #include "qgsvectorlayer.h"
31 #include "qgsprovidermetadata.h"
32 
33 #include <QApplication>
34 #include <QtConcurrentMap>
35 #include <QtConcurrentRun>
36 #include <QDateTime>
37 #include <QElapsedTimer>
38 #include <QDir>
39 #include <QFileInfo>
40 #include <QMenu>
41 #include <QMouseEvent>
42 #include <QTreeWidget>
43 #include <QTreeWidgetItem>
44 #include <QVector>
45 #include <QStyle>
46 #include <QTimer>
47 #include <mutex>
48 #include <QRegularExpression>
49 
50 // use GDAL VSI mechanism
51 #define CPL_SUPRESS_CPLUSPLUS //#spellok
52 #include "cpl_vsi.h"
53 #include "cpl_string.h"
54 
55 QgsAnimatedIcon *QgsDataItem::sPopulatingIcon = nullptr;
56 
57 QgsDataItem::QgsDataItem( Qgis::BrowserItemType type, QgsDataItem *parent, const QString &name, const QString &path, const QString &providerKey )
58 // Do not pass parent to QObject, Qt would delete this when parent is deleted
59  : mType( type )
60  , mParent( parent )
61  , mName( name )
62  , mProviderKey( providerKey )
63  , mPath( path )
64 {
65 }
66 
68 {
69  QgsDebugMsgLevel( QStringLiteral( "mName = %1 mPath = %2 mChildren.size() = %3" ).arg( mName, mPath ).arg( mChildren.size() ), 2 );
70  const auto constMChildren = mChildren;
71  for ( QgsDataItem *child : constMChildren )
72  {
73  if ( !child ) // should not happen
74  continue;
75  child->deleteLater();
76  }
77  mChildren.clear();
78 
79  if ( mFutureWatcher && !mFutureWatcher->isFinished() )
80  {
81  // this should not usually happen (until the item was deleted directly when createChildren was running)
82  QgsDebugMsg( QStringLiteral( "mFutureWatcher not finished (should not happen) -> waitForFinished()" ) );
83  mDeferredDelete = true;
84  mFutureWatcher->waitForFinished();
85  }
86 
87  delete mFutureWatcher;
88 }
89 
90 QString QgsDataItem::pathComponent( const QString &string )
91 {
92  const thread_local QRegularExpression rx( "[\\\\/]" );
93  return QString( string ).replace( rx, QStringLiteral( "|" ) );
94 }
95 
96 QVariant QgsDataItem::sortKey() const
97 {
98  return mSortKey.isValid() ? mSortKey : name();
99 }
100 
101 void QgsDataItem::setSortKey( const QVariant &key )
102 {
103  mSortKey = key;
104 }
105 
107 {
108  QgsDebugMsgLevel( "path = " + path(), 3 );
109  setParent( nullptr ); // also disconnects parent
110  const auto constMChildren = mChildren;
111  for ( QgsDataItem *child : constMChildren )
112  {
113  if ( !child ) // should not happen
114  continue;
115  child->deleteLater();
116  }
117  mChildren.clear();
118 
119  if ( mFutureWatcher && !mFutureWatcher->isFinished() )
120  {
121  QgsDebugMsg( QStringLiteral( "mFutureWatcher not finished -> schedule to delete later" ) );
122  mDeferredDelete = true;
123  }
124  else
125  {
126  QObject::deleteLater();
127  }
128 }
129 
130 void QgsDataItem::deleteLater( QVector<QgsDataItem *> &items )
131 {
132  const auto constItems = items;
133  for ( QgsDataItem *item : constItems )
134  {
135  if ( !item ) // should not happen
136  continue;
137  item->deleteLater();
138  }
139  items.clear();
140 }
141 
142 void QgsDataItem::moveToThread( QThread *targetThread )
143 {
144  // QObject::moveToThread() cannot move objects with parent, but QgsDataItem is not using paren/children from QObject
145  const auto constMChildren = mChildren;
146  for ( QgsDataItem *child : constMChildren )
147  {
148  if ( !child ) // should not happen
149  continue;
150  QgsDebugMsgLevel( "moveToThread child " + child->path(), 3 );
151  child->QObject::setParent( nullptr ); // to be sure
152  child->moveToThread( targetThread );
153  }
154  QObject::moveToThread( targetThread );
155 }
156 
158 {
159  return nullptr;
160 }
161 
163 {
164  if ( state() == Qgis::BrowserItemState::Populating && sPopulatingIcon )
165  return sPopulatingIcon->icon();
166 
167  if ( !mIcon.isNull() )
168  return mIcon;
169 
170  if ( !mIconMap.contains( mIconName ) )
171  {
172  mIconMap.insert( mIconName, mIconName.startsWith( ':' ) ? QIcon( mIconName ) : QgsApplication::getThemeIcon( mIconName ) );
173  }
174 
175  return mIconMap.value( mIconName );
176 }
177 
178 void QgsDataItem::setName( const QString &name )
179 {
180  mName = name;
181  emit dataChanged( this );
182 }
183 
184 QVector<QgsDataItem *> QgsDataItem::createChildren()
185 {
186  return QVector<QgsDataItem *>();
187 }
188 
189 void QgsDataItem::populate( bool foreground )
190 {
192  return;
193 
194  QgsDebugMsgLevel( "mPath = " + mPath, 2 );
195 
196  if ( capabilities2() & Qgis::BrowserItemCapability::Fast || foreground )
197  {
199  }
200  else
201  {
203  // The watcher must not be created with item (in constructor) because the item may be created in thread and the watcher created in thread does not work correctly.
204  if ( !mFutureWatcher )
205  {
206  mFutureWatcher = new QFutureWatcher< QVector <QgsDataItem *> >( this );
207  }
208 
209  connect( mFutureWatcher, &QFutureWatcherBase::finished, this, &QgsDataItem::childrenCreated );
210  mFutureWatcher->setFuture( QtConcurrent::run( runCreateChildren, this ) );
211  }
212 }
213 
214 // This is expected to be run in a separate thread
215 QVector<QgsDataItem *> QgsDataItem::runCreateChildren( QgsDataItem *item )
216 {
217  QgsDebugMsgLevel( "path = " + item->path(), 2 );
218  QElapsedTimer time;
219  time.start();
220  QVector <QgsDataItem *> children = item->createChildren();
221  QgsDebugMsgLevel( QStringLiteral( "%1 children created in %2 ms" ).arg( children.size() ).arg( time.elapsed() ), 3 );
222  // Children objects must be pushed to main thread.
223  const auto constChildren = children;
224  for ( QgsDataItem *child : constChildren )
225  {
226  if ( !child ) // should not happen
227  continue;
228  QgsDebugMsgLevel( "moveToThread child " + child->path(), 2 );
229  if ( qApp )
230  child->moveToThread( qApp->thread() ); // moves also children
231  }
232  QgsDebugMsgLevel( QStringLiteral( "finished path %1: %2 children" ).arg( item->path() ).arg( children.size() ), 3 );
233  return children;
234 }
235 
237 {
238  QgsDebugMsgLevel( QStringLiteral( "path = %1 children.size() = %2" ).arg( path() ).arg( mFutureWatcher->result().size() ), 3 );
239 
240  if ( deferredDelete() )
241  {
242  QgsDebugMsg( QStringLiteral( "Item was scheduled to be deleted later" ) );
243  QObject::deleteLater();
244  return;
245  }
246 
247  if ( mChildren.isEmpty() ) // usually populating but may also be refresh if originally there were no children
248  {
249  populate( mFutureWatcher->result() );
250  }
251  else // refreshing
252  {
253  refresh( mFutureWatcher->result() );
254  }
255  disconnect( mFutureWatcher, &QFutureWatcherBase::finished, this, &QgsDataItem::childrenCreated );
256  emit dataChanged( this ); // to replace loading icon by normal icon
257 }
258 
260 {
261  emit dataChanged( this );
262 }
263 
264 void QgsDataItem::populate( const QVector<QgsDataItem *> &children )
265 {
266  QgsDebugMsgLevel( "mPath = " + mPath, 3 );
267 
268  const auto constChildren = children;
269  for ( QgsDataItem *child : constChildren )
270  {
271  if ( !child ) // should not happen
272  continue;
273  // update after thread finished -> refresh
274  addChildItem( child, true );
275  }
277 }
278 
280 {
281  QgsDebugMsgLevel( "mPath = " + mPath, 3 );
282 
283  const auto constMChildren = mChildren;
284  for ( QgsDataItem *child : constMChildren )
285  {
286  QgsDebugMsgLevel( "remove " + child->path(), 3 );
287  child->depopulate(); // recursive
288  deleteChildItem( child );
289  }
291 }
292 
294 {
296  return;
297 
298  QgsDebugMsgLevel( "mPath = " + mPath, 3 );
299 
301  {
302  refresh( createChildren() );
303  }
304  else
305  {
307  if ( !mFutureWatcher )
308  {
309  mFutureWatcher = new QFutureWatcher< QVector <QgsDataItem *> >( this );
310  }
311  connect( mFutureWatcher, &QFutureWatcherBase::finished, this, &QgsDataItem::childrenCreated );
312  mFutureWatcher->setFuture( QtConcurrent::run( runCreateChildren, this ) );
313  }
314 }
315 
316 void QgsDataItem::refreshConnections( const QString &key )
317 {
318  // Walk up until the root node is reached
319  if ( mParent )
320  {
321  mParent->refreshConnections( key );
322  }
323  else
324  {
325  // if a specific key was specified then we use that -- otherwise we assume the connections
326  // changed belong to the same provider as this item
327  emit connectionsChanged( key.isEmpty() ? providerKey() : key );
328  }
329 }
330 
331 void QgsDataItem::refresh( const QVector<QgsDataItem *> &children )
332 {
333  QgsDebugMsgLevel( "mPath = " + mPath, 2 );
334 
335  // Remove no more present children
336  QVector<QgsDataItem *> remove;
337  const auto constMChildren = mChildren;
338  for ( QgsDataItem *child : constMChildren )
339  {
340  if ( !child ) // should not happen
341  continue;
342  if ( findItem( children, child ) >= 0 )
343  continue;
344  remove.append( child );
345  }
346  const auto constRemove = remove;
347  for ( QgsDataItem *child : constRemove )
348  {
349  QgsDebugMsgLevel( "remove " + child->path(), 3 );
350  deleteChildItem( child );
351  }
352 
353  // Add new children
354  const auto constChildren = children;
355  for ( QgsDataItem *child : constChildren )
356  {
357  if ( !child ) // should not happen
358  continue;
359 
360  const int index = findItem( mChildren, child );
361  if ( index >= 0 )
362  {
363  // Refresh recursively (some providers may create more generations of descendants)
364  if ( !( child->capabilities2() & Qgis::BrowserItemCapability::Fertile ) )
365  {
366  // The child cannot createChildren() itself
367  mChildren.value( index )->refresh( child->children() );
368  }
369  else if ( mChildren.value( index )->state() == Qgis::BrowserItemState::Populated
371  {
372  mChildren.value( index )->refresh();
373  }
374 
375  child->deleteLater();
376  continue;
377  }
378  addChildItem( child, true );
379  }
381 }
382 
384 {
385  return mProviderKey;
386 }
387 
388 void QgsDataItem::setProviderKey( const QString &value )
389 {
390  mProviderKey = value;
391 }
392 
394 {
395  return mChildren.size();
396 }
398 {
399  return ( state() == Qgis::BrowserItemState::Populated ? !mChildren.isEmpty() : true );
400 }
401 
403 {
404  return false;
405 }
406 
408 {
409  if ( mParent )
410  {
411  disconnect( this, nullptr, mParent, nullptr );
412  }
413  if ( parent )
414  {
421  }
422  mParent = parent;
423 }
424 
425 void QgsDataItem::addChildItem( QgsDataItem *child, bool refresh )
426 {
427  Q_ASSERT( child );
428  QgsDebugMsgLevel( QStringLiteral( "path = %1 add child #%2 - %3 - %4" ).arg( mPath ).arg( mChildren.size() ).arg( child->mName ).arg( qgsEnumValueToKey< Qgis::BrowserItemType >( child->mType ) ), 3 );
429 
430  //calculate position to insert child
431  int i;
433  {
434  for ( i = 0; i < mChildren.size(); i++ )
435  {
436  // sort items by type, so directories are before data items
437  if ( mChildren.at( i )->mType == child->mType &&
438  mChildren.at( i )->mName.localeAwareCompare( child->mName ) > 0 )
439  break;
440  }
441  }
442  else
443  {
444  for ( i = 0; i < mChildren.size(); i++ )
445  {
446  if ( mChildren.at( i )->mName.localeAwareCompare( child->mName ) >= 0 )
447  break;
448  }
449  }
450 
451  if ( refresh )
452  emit beginInsertItems( this, i, i );
453 
454  mChildren.insert( i, child );
455  child->setParent( this );
456 
457  if ( refresh )
458  emit endInsertItems();
459 }
460 
462 {
463  QgsDebugMsgLevel( "mName = " + child->mName, 2 );
464  const int i = mChildren.indexOf( child );
465  Q_ASSERT( i >= 0 );
466  emit beginRemoveItems( this, i, i );
467  mChildren.remove( i );
468  child->deleteLater();
469  emit endRemoveItems();
470 }
471 
473 {
474  QgsDebugMsgLevel( "mName = " + child->mName, 2 );
475  const int i = mChildren.indexOf( child );
476  Q_ASSERT( i >= 0 );
477  if ( i < 0 )
478  {
479  child->setParent( nullptr );
480  return nullptr;
481  }
482 
483  emit beginRemoveItems( this, i, i );
484  mChildren.remove( i );
485  emit endRemoveItems();
486  return child;
487 }
488 
489 int QgsDataItem::findItem( QVector<QgsDataItem *> items, QgsDataItem *item )
490 {
491  for ( int i = 0; i < items.size(); i++ )
492  {
493  Q_ASSERT_X( items[i], "findItem", QStringLiteral( "item %1 is nullptr" ).arg( i ).toLatin1() );
494  QgsDebugMsgLevel( QString::number( i ) + " : " + items[i]->mPath + " x " + item->mPath, 2 );
495  if ( items[i]->equal( item ) )
496  return i;
497  }
498  return -1;
499 }
500 
501 bool QgsDataItem::equal( const QgsDataItem *other )
502 {
503  return ( metaObject()->className() == other->metaObject()->className() &&
504  mPath == other->path() );
505 }
506 
507 QList<QAction *> QgsDataItem::actions( QWidget *parent )
508 {
509  Q_UNUSED( parent )
510  return QList<QAction *>();
511 }
512 
514 {
515  return false;
516 }
517 
519 {
520  return mimeUris().isEmpty() ? QgsMimeDataUtils::Uri() : mimeUris().constFirst();
521 }
522 
524 {
526  {
528  uri.uri = path();
529  uri.filePath = path();
530  return { uri };
531  }
532 
533  return {};
534 }
535 
537 {
538  Q_UNUSED( crs )
539  return false;
540 }
541 
542 bool QgsDataItem::rename( const QString & )
543 {
544  return false;
545 }
546 
547 void QgsDataItem::setCapabilities( int capabilities )
548 {
549  setCapabilities( static_cast< Qgis::BrowserItemCapabilities >( capabilities ) );
550 }
551 
553 {
554  return mState;
555 }
556 
558 {
559  QgsDebugMsgLevel( QStringLiteral( "item %1 set state %2 -> %3" ).arg( path() ).arg( qgsEnumValueToKey< Qgis::BrowserItemState >( this->state() ) ).arg( qgsEnumValueToKey< Qgis::BrowserItemState >( state ) ), 3 );
560  if ( state == mState )
561  return;
562 
563  const Qgis::BrowserItemState oldState = mState;
564 
565  if ( state == Qgis::BrowserItemState::Populating ) // start loading
566  {
567  if ( !sPopulatingIcon )
568  {
569  // TODO: ensure that QgsAnimatedIcon is created on UI thread only
570  sPopulatingIcon = new QgsAnimatedIcon( QgsApplication::iconPath( QStringLiteral( "/mIconLoading.gif" ) ), QgsApplication::instance() );
571  }
572 
573  sPopulatingIcon->connectFrameChanged( this, &QgsDataItem::updateIcon );
574  }
575  else if ( mState == Qgis::BrowserItemState::Populating && sPopulatingIcon ) // stop loading
576  {
577  sPopulatingIcon->disconnectFrameChanged( this, &QgsDataItem::updateIcon );
578  }
579 
580 
581  mState = state;
582 
583  emit stateChanged( this, oldState );
585  updateIcon();
586 }
587 
588 QList<QMenu *> QgsDataItem::menus( QWidget *parent )
589 {
590  Q_UNUSED( parent )
591  return QList<QMenu *>();
592 }
593 
594 QgsErrorItem::QgsErrorItem( QgsDataItem *parent, const QString &error, const QString &path )
595  : QgsDataItem( Qgis::BrowserItemType::Error, parent, error, path )
596 {
597  mIconName = QStringLiteral( "/mIconDelete.svg" );
598 
599  setState( Qgis::BrowserItemState::Populated ); // no more children
600 }
601 
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:72
BrowserItemState
Browser item states.
Definition: qgis.h:364
@ NotPopulated
Children not yet created.
@ Populating
Creating children in separate thread (populating or refreshing)
@ Populated
Children created.
@ Fertile
Can create children. Even items without this capability may have children, but cannot create them,...
@ RefreshChildrenWhenItemIsRefreshed
When the item is refreshed, all its populated children will also be refreshed in turn (since QGIS 3....
@ ItemRepresentsFile
Item's path() directly represents a file on disk (since QGIS 3.22)
@ Fast
CreateChildren() is fast enough to be run in main thread when refreshing items, most root items (wms,...
BrowserItemType
Symbol layer flags.
Definition: qgis.h:345
@ Directory
Represents a file directory.
The QgsAbstractDatabaseProviderConnection class provides common functionality for DB based connection...
Animated icon is keeping an animation running if there are listeners connected to frameChanged.
bool disconnectFrameChanged(const typename QtPrivate::FunctionPointer< Func1 >::Object *receiver, Func1 slot)
Convenience function to disconnect the same style that the frame change connection was established.
bool connectFrameChanged(const typename QtPrivate::FunctionPointer< Func1 >::Object *receiver, Func1 slot)
Connect a slot that will be notified repeatedly whenever a frame changes and which should request the...
QIcon icon() const
Gets the icons representation in the current frame.
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
This class represents a coordinate reference system (CRS).
Base class for all items in the model.
Definition: qgsdataitem.h:46
void stateChanged(QgsDataItem *item, Qgis::BrowserItemState oldState)
Emitted when an item's state is changed.
void setSortKey(const QVariant &key)
Sets a custom sorting key for the item.
static int findItem(QVector< QgsDataItem * > items, QgsDataItem *item)
QString mName
Definition: qgsdataitem.h:449
Qgis::BrowserItemType mType
Definition: qgsdataitem.h:444
bool hasChildren()
virtual QList< QMenu * > menus(QWidget *parent)
Returns the list of menus available for this item.
virtual void deleteChildItem(QgsDataItem *child)
Removes and deletes a child item, emitting relevant signals to the model.
QVector< QgsDataItem * > mChildren
Definition: qgsdataitem.h:447
virtual QVariant sortKey() const
Returns the sorting key for the item.
Definition: qgsdataitem.cpp:96
Qgis::BrowserItemState mState
Definition: qgsdataitem.h:448
virtual bool handleDoubleClick()
Called when a user double clicks on the item.
void dataChanged(QgsDataItem *item)
bool deferredDelete()
The item is scheduled to be deleted.
Definition: qgsdataitem.h:442
void setParent(QgsDataItem *parent)
Set item parent and connect / disconnect parent to / from item signals.
static void deleteLater(QVector< QgsDataItem * > &items)
void endRemoveItems()
virtual bool layerCollection() const
Returns true if the data item is a collection of layers The default implementation returns false,...
QString mPath
Definition: qgsdataitem.h:455
QVector< QgsDataItem * > children() const
Definition: qgsdataitem.h:337
void beginRemoveItems(QgsDataItem *parent, int first, int last)
QgsDataItem * parent() const
Gets item parent.
Definition: qgsdataitem.h:330
virtual void deleteLater()
Safely delete the item:
virtual QgsAbstractDatabaseProviderConnection * databaseConnection() const
For data items that represent a DB connection or one of its children, this method returns a connectio...
Qgis::BrowserItemType type() const
Definition: qgsdataitem.h:324
QgsDataItem(Qgis::BrowserItemType type, QgsDataItem *parent, const QString &name, const QString &path, const QString &providerKey=QString())
Constructor for QgsDataItem, with the specified parent item.
Definition: qgsdataitem.cpp:57
QString mIconName
Definition: qgsdataitem.h:457
virtual QVector< QgsDataItem * > createChildren()
Create children.
QMap< QString, QIcon > mIconMap
Definition: qgsdataitem.h:459
Qgis::BrowserItemState state() const
virtual void childrenCreated()
virtual QgsDataItem * removeChildItem(QgsDataItem *child)
Removes a child item and returns it without deleting it.
static QString pathComponent(const QString &component)
Create path component replacing path separators.
Definition: qgsdataitem.cpp:90
virtual QList< QAction * > actions(QWidget *parent)
Returns the list of actions available for this item.
QVariant mSortKey
Custom sort key. If invalid, name() will be used for sorting instead.
Definition: qgsdataitem.h:462
void updateIcon()
Will request a repaint of this icon.
virtual Q_DECL_DEPRECATED bool rename(const QString &name)
Sets a new name for the item, and returns true if the item was successfully renamed.
void connectionsChanged(const QString &providerKey=QString())
Emitted when the connections of the provider with the specified providerKey have changed.
virtual Q_DECL_DEPRECATED QgsMimeDataUtils::Uri mimeUri() const
Returns mime URI for the data item.
QgsDataItem * mParent
Definition: qgsdataitem.h:446
QString name() const
Returns the name of the item (the displayed text for the item).
Definition: qgsdataitem.h:345
QString path() const
Definition: qgsdataitem.h:354
virtual QIcon icon()
virtual void setState(Qgis::BrowserItemState state)
Set item state.
void beginInsertItems(QgsDataItem *parent, int first, int last)
virtual void refreshConnections(const QString &providerKey=QString())
Causes a data item provider to refresh all registered connections.
virtual void setCapabilities(Qgis::BrowserItemCapabilities capabilities)
Sets the capabilities for the data item.
Definition: qgsdataitem.h:310
virtual void addChildItem(QgsDataItem *child, bool refresh=false)
Inserts a new child item.
void setName(const QString &name)
Sets the name of the item (the displayed text for the item).
virtual void refresh()
void moveToThread(QThread *targetThread)
Move object and all its descendants to thread.
virtual QgsMimeDataUtils::UriList mimeUris() const
Returns mime URIs for the data item, most data providers will only return a single URI but some data ...
QString providerKey() const
Returns the provider key that created this item (e.g.
void endInsertItems()
virtual Q_DECL_DEPRECATED bool setCrs(const QgsCoordinateReferenceSystem &crs)
Writes the selected crs into data source.
virtual Qgis::BrowserItemCapabilities capabilities2() const
Returns the capabilities for the data item.
Definition: qgsdataitem.h:303
~QgsDataItem() override
Definition: qgsdataitem.cpp:67
void setProviderKey(const QString &value)
Sets the provider key that created this item (e.g.
QString mProviderKey
Definition: qgsdataitem.h:450
virtual void populate(const QVector< QgsDataItem * > &children)
virtual bool equal(const QgsDataItem *other)
Returns true if this item is equal to another item (by testing item type and path).
virtual void depopulate()
Remove children recursively and set as not populated. This is used when refreshing collapsed items.
QgsErrorItem(QgsDataItem *parent, const QString &error, const QString &path)
QList< QgsMimeDataUtils::Uri > UriList
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
const QgsCoordinateReferenceSystem & crs
QString filePath
Path to file, if uri is associated with a file.
QString uri
Identifier of the data source recognized by its providerKey.