QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 <QApplication>
19 #include <QtConcurrentMap>
20 #include <QtConcurrentRun>
21 #include <QDateTime>
22 #include <QElapsedTimer>
23 #include <QDir>
24 #include <QFileInfo>
25 #include <QMenu>
26 #include <QMouseEvent>
27 #include <QTreeWidget>
28 #include <QTreeWidgetItem>
29 #include <QVector>
30 #include <QStyle>
31 #include <mutex>
32 
33 #include "qgis.h"
34 #include "qgsdataitem.h"
35 #include "qgsapplication.h"
36 #include "qgsdataitemprovider.h"
38 #include "qgsdataprovider.h"
39 #include "qgslogger.h"
40 #include "qgsproviderregistry.h"
41 #include "qgsconfig.h"
42 #include "qgssettings.h"
43 #include "qgsanimatedicon.h"
44 #include "qgsproject.h"
45 #include "qgsvectorlayer.h"
46 
47 // use GDAL VSI mechanism
48 #define CPL_SUPRESS_CPLUSPLUS //#spellok
49 #include "cpl_vsi.h"
50 #include "cpl_string.h"
51 
52 // shared icons
54 {
55  return QgsApplication::getThemeIcon( QStringLiteral( "/mIconPointLayer.svg" ) );
56 }
57 
59 {
60  return QgsApplication::getThemeIcon( QStringLiteral( "/mIconLineLayer.svg" ) );
61 }
62 
64 {
65  return QgsApplication::getThemeIcon( QStringLiteral( "/mIconPolygonLayer.svg" ) );
66 }
67 
69 {
70  return QgsApplication::getThemeIcon( QStringLiteral( "/mIconTableLayer.svg" ) );
71 }
72 
74 {
75  return QgsApplication::getThemeIcon( QStringLiteral( "/mIconRaster.svg" ) );
76 }
77 
79 {
80  return QgsApplication::getThemeIcon( QStringLiteral( "/mIconMeshLayer.svg" ) );
81 }
82 
84 {
85  return QgsApplication::getThemeIcon( QStringLiteral( "/mIconVectorTileLayer.svg" ) );
86 }
87 
89 {
90  return QgsApplication::getThemeIcon( QStringLiteral( "/mIconLayer.png" ) );
91 }
92 
94 {
95  return QgsApplication::getThemeIcon( QStringLiteral( "/mIconDbSchema.svg" ) );
96 }
97 
99 {
100  return QgsApplication::getThemeIcon( QStringLiteral( "/mIconFolderOpen.svg" ) );
101 }
102 
104 {
105  return QgsApplication::getThemeIcon( QStringLiteral( "mIconFolderHome.svg" ) );
106 }
107 
109 {
110  return QgsApplication::getThemeIcon( QStringLiteral( "/mIconFolder.svg" ) );
111 }
112 
114 {
115  return QgsApplication::getThemeIcon( QStringLiteral( "/mIconFavourites.svg" ) );
116 }
117 
119 {
120  return QStringLiteral( " 0" );
121 }
122 
124 {
125  return QgsApplication::getThemeIcon( QStringLiteral( "/mIconZip.svg" ) );
126 }
127 
128 QgsAnimatedIcon *QgsDataItem::sPopulatingIcon = nullptr;
129 
130 QgsDataItem::QgsDataItem( QgsDataItem::Type type, QgsDataItem *parent, const QString &name, const QString &path, const QString &providerKey )
131 // Do not pass parent to QObject, Qt would delete this when parent is deleted
132  : mType( type )
133  , mCapabilities( NoCapabilities )
134  , mParent( parent )
135  , mState( NotPopulated )
136  , mName( name )
137  , mProviderKey( providerKey )
138  , mPath( path )
139  , mDeferredDelete( false )
140  , mFutureWatcher( nullptr )
141 {
142 }
143 
145 {
146  QgsDebugMsgLevel( QStringLiteral( "mName = %1 mPath = %2 mChildren.size() = %3" ).arg( mName, mPath ).arg( mChildren.size() ), 2 );
147  const auto constMChildren = mChildren;
148  for ( QgsDataItem *child : constMChildren )
149  {
150  if ( !child ) // should not happen
151  continue;
152  child->deleteLater();
153  }
154  mChildren.clear();
155 
156  if ( mFutureWatcher && !mFutureWatcher->isFinished() )
157  {
158  // this should not usually happen (until the item was deleted directly when createChildren was running)
159  QgsDebugMsg( QStringLiteral( "mFutureWatcher not finished (should not happen) -> waitForFinished()" ) );
160  mDeferredDelete = true;
161  mFutureWatcher->waitForFinished();
162  }
163 
164  delete mFutureWatcher;
165 }
166 
167 QString QgsDataItem::pathComponent( const QString &string )
168 {
169  return QString( string ).replace( QRegExp( "[\\\\/]" ), QStringLiteral( "|" ) );
170 }
171 
172 QVariant QgsDataItem::sortKey() const
173 {
174  return mSortKey.isValid() ? mSortKey : name();
175 }
176 
177 void QgsDataItem::setSortKey( const QVariant &key )
178 {
179  mSortKey = key;
180 }
181 
183 {
184  QgsDebugMsgLevel( "path = " + path(), 3 );
185  setParent( nullptr ); // also disconnects parent
186  const auto constMChildren = mChildren;
187  for ( QgsDataItem *child : constMChildren )
188  {
189  if ( !child ) // should not happen
190  continue;
191  child->deleteLater();
192  }
193  mChildren.clear();
194 
195  if ( mFutureWatcher && !mFutureWatcher->isFinished() )
196  {
197  QgsDebugMsg( QStringLiteral( "mFutureWatcher not finished -> schedule to delete later" ) );
198  mDeferredDelete = true;
199  }
200  else
201  {
202  QObject::deleteLater();
203  }
204 }
205 
206 void QgsDataItem::deleteLater( QVector<QgsDataItem *> &items )
207 {
208  const auto constItems = items;
209  for ( QgsDataItem *item : constItems )
210  {
211  if ( !item ) // should not happen
212  continue;
213  item->deleteLater();
214  }
215  items.clear();
216 }
217 
218 void QgsDataItem::moveToThread( QThread *targetThread )
219 {
220  // QObject::moveToThread() cannot move objects with parent, but QgsDataItem is not using paren/children from QObject
221  const auto constMChildren = mChildren;
222  for ( QgsDataItem *child : constMChildren )
223  {
224  if ( !child ) // should not happen
225  continue;
226  QgsDebugMsgLevel( "moveToThread child " + child->path(), 3 );
227  child->QObject::setParent( nullptr ); // to be sure
228  child->moveToThread( targetThread );
229  }
230  QObject::moveToThread( targetThread );
231 }
232 
234 {
235  if ( state() == Populating && sPopulatingIcon )
236  return sPopulatingIcon->icon();
237 
238  if ( !mIcon.isNull() )
239  return mIcon;
240 
241  if ( !mIconMap.contains( mIconName ) )
242  {
243  mIconMap.insert( mIconName, mIconName.startsWith( ':' ) ? QIcon( mIconName ) : QgsApplication::getThemeIcon( mIconName ) );
244  }
245 
246  return mIconMap.value( mIconName );
247 }
248 
249 void QgsDataItem::setName( const QString &name )
250 {
251  mName = name;
252  emit dataChanged( this );
253 }
254 
255 QVector<QgsDataItem *> QgsDataItem::createChildren()
256 {
257  return QVector<QgsDataItem *>();
258 }
259 
260 void QgsDataItem::populate( bool foreground )
261 {
262  if ( state() == Populated || state() == Populating )
263  return;
264 
265  QgsDebugMsgLevel( "mPath = " + mPath, 2 );
266 
267  if ( capabilities2() & QgsDataItem::Fast || foreground )
268  {
270  }
271  else
272  {
273  setState( Populating );
274  // 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.
275  if ( !mFutureWatcher )
276  {
277  mFutureWatcher = new QFutureWatcher< QVector <QgsDataItem *> >( this );
278  }
279 
280  connect( mFutureWatcher, &QFutureWatcherBase::finished, this, &QgsDataItem::childrenCreated );
281  mFutureWatcher->setFuture( QtConcurrent::run( runCreateChildren, this ) );
282  }
283 }
284 
285 // This is expected to be run in a separate thread
286 QVector<QgsDataItem *> QgsDataItem::runCreateChildren( QgsDataItem *item )
287 {
288  QgsDebugMsgLevel( "path = " + item->path(), 2 );
289  QElapsedTimer time;
290  time.start();
291  QVector <QgsDataItem *> children = item->createChildren();
292  QgsDebugMsgLevel( QStringLiteral( "%1 children created in %2 ms" ).arg( children.size() ).arg( time.elapsed() ), 3 );
293  // Children objects must be pushed to main thread.
294  const auto constChildren = children;
295  for ( QgsDataItem *child : constChildren )
296  {
297  if ( !child ) // should not happen
298  continue;
299  QgsDebugMsgLevel( "moveToThread child " + child->path(), 2 );
300  if ( qApp )
301  child->moveToThread( qApp->thread() ); // moves also children
302  }
303  QgsDebugMsgLevel( QStringLiteral( "finished path %1: %2 children" ).arg( item->path() ).arg( children.size() ), 3 );
304  return children;
305 }
306 
308 {
309  QgsDebugMsgLevel( QStringLiteral( "path = %1 children.size() = %2" ).arg( path() ).arg( mFutureWatcher->result().size() ), 3 );
310 
311  if ( deferredDelete() )
312  {
313  QgsDebugMsg( QStringLiteral( "Item was scheduled to be deleted later" ) );
314  QObject::deleteLater();
315  return;
316  }
317 
318  if ( mChildren.isEmpty() ) // usually populating but may also be refresh if originally there were no children
319  {
320  populate( mFutureWatcher->result() );
321  }
322  else // refreshing
323  {
324  refresh( mFutureWatcher->result() );
325  }
326  disconnect( mFutureWatcher, &QFutureWatcherBase::finished, this, &QgsDataItem::childrenCreated );
327  emit dataChanged( this ); // to replace loading icon by normal icon
328 }
329 
331 {
332  emit dataChanged( this );
333 }
334 
335 void QgsDataItem::populate( const QVector<QgsDataItem *> &children )
336 {
337  QgsDebugMsgLevel( "mPath = " + mPath, 3 );
338 
339  const auto constChildren = children;
340  for ( QgsDataItem *child : constChildren )
341  {
342  if ( !child ) // should not happen
343  continue;
344  // update after thread finished -> refresh
345  addChildItem( child, true );
346  }
347  setState( Populated );
348 }
349 
351 {
352  QgsDebugMsgLevel( "mPath = " + mPath, 3 );
353 
354  const auto constMChildren = mChildren;
355  for ( QgsDataItem *child : constMChildren )
356  {
357  QgsDebugMsgLevel( "remove " + child->path(), 3 );
358  child->depopulate(); // recursive
359  deleteChildItem( child );
360  }
362 }
363 
365 {
366  if ( state() == Populating )
367  return;
368 
369  QgsDebugMsgLevel( "mPath = " + mPath, 3 );
370 
372  {
373  refresh( createChildren() );
374  }
375  else
376  {
377  setState( Populating );
378  if ( !mFutureWatcher )
379  {
380  mFutureWatcher = new QFutureWatcher< QVector <QgsDataItem *> >( this );
381  }
382  connect( mFutureWatcher, &QFutureWatcherBase::finished, this, &QgsDataItem::childrenCreated );
383  mFutureWatcher->setFuture( QtConcurrent::run( runCreateChildren, this ) );
384  }
385 }
386 
387 void QgsDataItem::refreshConnections( const QString &key )
388 {
389  // Walk up until the root node is reached
390  if ( mParent )
391  {
392  mParent->refreshConnections( key );
393  }
394  else
395  {
396  // if a specific key was specified then we use that -- otherwise we assume the connections
397  // changed belong to the same provider as this item
398  emit connectionsChanged( key.isEmpty() ? providerKey() : key );
399  }
400 }
401 
402 void QgsDataItem::refresh( const QVector<QgsDataItem *> &children )
403 {
404  QgsDebugMsgLevel( "mPath = " + mPath, 2 );
405 
406  // Remove no more present children
407  QVector<QgsDataItem *> remove;
408  const auto constMChildren = mChildren;
409  for ( QgsDataItem *child : constMChildren )
410  {
411  if ( !child ) // should not happen
412  continue;
413  if ( findItem( children, child ) >= 0 )
414  continue;
415  remove.append( child );
416  }
417  const auto constRemove = remove;
418  for ( QgsDataItem *child : constRemove )
419  {
420  QgsDebugMsgLevel( "remove " + child->path(), 3 );
421  deleteChildItem( child );
422  }
423 
424  // Add new children
425  const auto constChildren = children;
426  for ( QgsDataItem *child : constChildren )
427  {
428  if ( !child ) // should not happen
429  continue;
430 
431  int index = findItem( mChildren, child );
432  if ( index >= 0 )
433  {
434  // Refresh recursively (some providers may create more generations of descendants)
435  if ( !( child->capabilities2() & QgsDataItem::Fertile ) )
436  {
437  // The child cannot createChildren() itself
438  mChildren.value( index )->refresh( child->children() );
439  }
440 
441  child->deleteLater();
442  continue;
443  }
444  addChildItem( child, true );
445  }
446  setState( Populated );
447 }
448 
450 {
451  return mProviderKey;
452 }
453 
454 void QgsDataItem::setProviderKey( const QString &value )
455 {
456  mProviderKey = value;
457 }
458 
460 {
461  return mChildren.size();
462 }
464 {
465  return ( state() == Populated ? !mChildren.isEmpty() : true );
466 }
467 
469 {
470  return false;
471 }
472 
474 {
475  if ( mParent )
476  {
477  disconnect( this, nullptr, mParent, nullptr );
478  }
479  if ( parent )
480  {
487  }
488  mParent = parent;
489 }
490 
491 void QgsDataItem::addChildItem( QgsDataItem *child, bool refresh )
492 {
493  Q_ASSERT( child );
494  QgsDebugMsgLevel( QStringLiteral( "path = %1 add child #%2 - %3 - %4" ).arg( mPath ).arg( mChildren.size() ).arg( child->mName ).arg( child->mType ), 3 );
495 
496  //calculate position to insert child
497  int i;
498  if ( type() == Directory )
499  {
500  for ( i = 0; i < mChildren.size(); i++ )
501  {
502  // sort items by type, so directories are before data items
503  if ( mChildren.at( i )->mType == child->mType &&
504  mChildren.at( i )->mName.localeAwareCompare( child->mName ) > 0 )
505  break;
506  }
507  }
508  else
509  {
510  for ( i = 0; i < mChildren.size(); i++ )
511  {
512  if ( mChildren.at( i )->mName.localeAwareCompare( child->mName ) >= 0 )
513  break;
514  }
515  }
516 
517  if ( refresh )
518  emit beginInsertItems( this, i, i );
519 
520  mChildren.insert( i, child );
521  child->setParent( this );
522 
523  if ( refresh )
524  emit endInsertItems();
525 }
526 
528 {
529  QgsDebugMsgLevel( "mName = " + child->mName, 2 );
530  int i = mChildren.indexOf( child );
531  Q_ASSERT( i >= 0 );
532  emit beginRemoveItems( this, i, i );
533  mChildren.remove( i );
534  child->deleteLater();
535  emit endRemoveItems();
536 }
537 
539 {
540  QgsDebugMsgLevel( "mName = " + child->mName, 2 );
541  int i = mChildren.indexOf( child );
542  Q_ASSERT( i >= 0 );
543  if ( i < 0 )
544  {
545  child->setParent( nullptr );
546  return nullptr;
547  }
548 
549  emit beginRemoveItems( this, i, i );
550  mChildren.remove( i );
551  emit endRemoveItems();
552  return child;
553 }
554 
555 int QgsDataItem::findItem( QVector<QgsDataItem *> items, QgsDataItem *item )
556 {
557  for ( int i = 0; i < items.size(); i++ )
558  {
559  Q_ASSERT_X( items[i], "findItem", QStringLiteral( "item %1 is nullptr" ).arg( i ).toLatin1() );
560  QgsDebugMsgLevel( QString::number( i ) + " : " + items[i]->mPath + " x " + item->mPath, 2 );
561  if ( items[i]->equal( item ) )
562  return i;
563  }
564  return -1;
565 }
566 
567 bool QgsDataItem::equal( const QgsDataItem *other )
568 {
569  return ( metaObject()->className() == other->metaObject()->className() &&
570  mPath == other->path() );
571 }
572 
573 QList<QAction *> QgsDataItem::actions( QWidget *parent )
574 {
575  Q_UNUSED( parent )
576  return QList<QAction *>();
577 }
578 
580 {
581  return false;
582 }
583 
584 bool QgsDataItem::rename( const QString & )
585 {
586  return false;
587 }
588 
590 {
591  return mState;
592 }
593 
595 {
596  QgsDebugMsgLevel( QStringLiteral( "item %1 set state %2 -> %3" ).arg( path() ).arg( this->state() ).arg( state ), 3 );
597  if ( state == mState )
598  return;
599 
600  State oldState = mState;
601 
602  if ( state == Populating ) // start loading
603  {
604  if ( !sPopulatingIcon )
605  {
606  // TODO: ensure that QgsAnimatedIcon is created on UI thread only
607  sPopulatingIcon = new QgsAnimatedIcon( QgsApplication::iconPath( QStringLiteral( "/mIconLoading.gif" ) ), QgsApplication::instance() );
608  }
609 
610  sPopulatingIcon->connectFrameChanged( this, &QgsDataItem::updateIcon );
611  }
612  else if ( mState == Populating && sPopulatingIcon ) // stop loading
613  {
614  sPopulatingIcon->disconnectFrameChanged( this, &QgsDataItem::updateIcon );
615  }
616 
617 
618  mState = state;
619 
620  emit stateChanged( this, oldState );
621  if ( state == Populated )
622  updateIcon();
623 }
624 
625 QList<QMenu *> QgsDataItem::menus( QWidget *parent )
626 {
627  Q_UNUSED( parent )
628  return QList<QMenu *>();
629 }
630 
631 // ---------------------------------------------------------------------
632 
633 QgsLayerItem::QgsLayerItem( QgsDataItem *parent, const QString &name, const QString &path,
634  const QString &uri, LayerType layerType, const QString &providerKey )
635  : QgsDataItem( Layer, parent, name, path, providerKey )
636  , mUri( uri )
637  , mLayerType( layerType )
638 {
639  mIconName = iconName( layerType );
640 }
641 
643 {
644  switch ( mLayerType )
645  {
648 
649  case QgsLayerItem::Mesh:
651 
654 
657 
660  case QgsLayerItem::Point:
662  case QgsLayerItem::Line:
664  case QgsLayerItem::Table:
667  }
668 
669  return QgsMapLayerType::VectorLayer; // no warnings
670 }
671 
673 {
674  switch ( layer->type() )
675  {
677  {
678  switch ( qobject_cast< QgsVectorLayer * >( layer )->geometryType() )
679  {
681  return Point;
682 
684  return Line;
685 
687  return Polygon;
688 
690  return TableLayer;
691 
693  return Vector;
694  }
695 
696  return Vector; // no warnings
697  }
698 
700  return Raster;
702  return Plugin;
704  return Mesh;
706  return VectorTile;
707  }
708  return Vector; // no warnings
709 }
710 
712 {
713  static int enumIdx = staticMetaObject.indexOfEnumerator( "LayerType" );
714  return staticMetaObject.enumerator( enumIdx ).valueToKey( layerType );
715 }
716 
718 {
719  switch ( layerType )
720  {
721  case Point:
722  return QStringLiteral( "/mIconPointLayer.svg" );
723  case Line:
724  return QStringLiteral( "/mIconLineLayer.svg" );
725  case Polygon:
726  return QStringLiteral( "/mIconPolygonLayer.svg" );
727  // TODO add a new icon for generic Vector layers
728  case Vector :
729  return QStringLiteral( "/mIconVector.svg" );
730  case TableLayer:
731  case Table:
732  return QStringLiteral( "/mIconTableLayer.svg" );
733  case Raster:
734  return QStringLiteral( "/mIconRaster.svg" );
735  case Mesh:
736  return QStringLiteral( "/mIconMeshLayer.svg" );
737  default:
738  return QStringLiteral( "/mIconLayer.png" );
739  }
740 }
741 
743 {
744  return false;
745 }
746 
747 bool QgsLayerItem::equal( const QgsDataItem *other )
748 {
749  //QgsDebugMsg ( mPath + " x " + other->mPath );
750  if ( type() != other->type() )
751  {
752  return false;
753  }
754  //const QgsLayerItem *o = qobject_cast<const QgsLayerItem *> ( other );
755  const QgsLayerItem *o = qobject_cast<const QgsLayerItem *>( other );
756  if ( !o )
757  return false;
758 
759  return ( mPath == o->mPath && mName == o->mName && mUri == o->mUri && mProviderKey == o->mProviderKey );
760 }
761 
763 {
765 
766  switch ( mapLayerType() )
767  {
769  u.layerType = QStringLiteral( "vector" );
770  switch ( mLayerType )
771  {
772  case Point:
774  break;
775  case Line:
777  break;
778  case Polygon:
780  break;
781  case TableLayer:
783  break;
784 
785  case Database:
786  case Table:
787  case NoType:
788  case Vector:
789  case Raster:
790  case Plugin:
791  case Mesh:
792  case VectorTile:
793  break;
794  }
795  break;
797  u.layerType = QStringLiteral( "raster" );
798  break;
800  u.layerType = QStringLiteral( "mesh" );
801  break;
803  u.layerType = QStringLiteral( "vector-tile" );
804  break;
806  u.layerType = QStringLiteral( "plugin" );
807  break;
808  }
809 
810  u.providerKey = providerKey();
811  u.name = layerName();
812  u.uri = uri();
815  return u;
816 }
817 
818 // ---------------------------------------------------------------------
820  const QString &name,
821  const QString &path,
822  const QString &providerKey )
823  : QgsDataItem( Collection, parent, name, path, providerKey )
824 {
826  mIconName = QStringLiteral( "/mIconDbSchema.svg" );
827 }
828 
830 {
831  QgsDebugMsgLevel( "mName = " + mName + " mPath = " + mPath, 2 );
832 
833 // Do not delete children, children are deleted by QObject parent
834 #if 0
835  const auto constMChildren = mChildren;
836  for ( QgsDataItem *i : constMChildren )
837  {
838  QgsDebugMsgLevel( QStringLiteral( "delete child = 0x%0" ).arg( static_cast<qlonglong>( i ), 8, 16, QLatin1Char( '0' ) ), 2 );
839  delete i;
840  }
841 #endif
842 }
843 
844 //-----------------------------------------------------------------------
845 
846 QgsDirectoryItem::QgsDirectoryItem( QgsDataItem *parent, const QString &name, const QString &path )
847  : QgsDataCollectionItem( parent, QDir::toNativeSeparators( name ), path )
848  , mDirPath( path )
849  , mRefreshLater( false )
850 {
851  mType = Directory;
852  init();
853 }
854 
855 QgsDirectoryItem::QgsDirectoryItem( QgsDataItem *parent, const QString &name,
856  const QString &dirPath, const QString &path,
857  const QString &providerKey )
858  : QgsDataCollectionItem( parent, QDir::toNativeSeparators( name ), path, providerKey )
859  , mDirPath( dirPath )
860  , mRefreshLater( false )
861 {
862  mType = Directory;
863  init();
864 }
865 
867 {
868  setToolTip( QDir::toNativeSeparators( mDirPath ) );
869 }
870 
872 {
873  if ( mDirPath == QDir::homePath() )
874  return homeDirIcon();
875 
876  // still loading? show the spinner
877  if ( state() == Populating )
878  return QgsDataItem::icon();
879 
880  // symbolic link? use link icon
881  QFileInfo fi( mDirPath );
882  if ( fi.isDir() && fi.isSymLink() )
883  {
884  return QgsApplication::getThemeIcon( QStringLiteral( "mIconFolderLink.svg" ) );
885  }
886 
887  // loaded? show the open dir icon
888  if ( state() == Populated )
889  return openDirIcon();
890 
891  // show the closed dir icon
892  return iconDir();
893 }
894 
895 
896 QVector<QgsDataItem *> QgsDirectoryItem::createChildren()
897 {
898  QVector<QgsDataItem *> children;
899  QDir dir( mDirPath );
900 
901  const QList<QgsDataItemProvider *> providers = QgsApplication::dataItemProviderRegistry()->providers();
902 
903  QStringList entries = dir.entryList( QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
904  const auto constEntries = entries;
905  for ( const QString &subdir : constEntries )
906  {
907  if ( mRefreshLater )
908  {
910  return children;
911  }
912 
913  QString subdirPath = dir.absoluteFilePath( subdir );
914 
915  QgsDebugMsgLevel( QStringLiteral( "creating subdir: %1" ).arg( subdirPath ), 2 );
916 
917  QString path = mPath + '/' + subdir; // may differ from subdirPath
919  continue;
920 
921  bool handledByProvider = false;
922  for ( QgsDataItemProvider *provider : providers )
923  {
924  if ( provider->handlesDirectoryPath( path ) )
925  {
926  handledByProvider = true;
927  break;
928  }
929  }
930  if ( handledByProvider )
931  continue;
932 
933  QgsDirectoryItem *item = new QgsDirectoryItem( this, subdir, subdirPath, path );
934 
935  // we want directories shown before files
936  item->setSortKey( QStringLiteral( " %1" ).arg( subdir ) );
937 
938  // propagate signals up to top
939 
940  children.append( item );
941  }
942 
943  QStringList fileEntries = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files, QDir::Name );
944  const auto constFileEntries = fileEntries;
945  for ( const QString &name : constFileEntries )
946  {
947  if ( mRefreshLater )
948  {
950  return children;
951  }
952 
953  QString path = dir.absoluteFilePath( name );
954  QFileInfo fileInfo( path );
955 
956  if ( fileInfo.suffix().compare( QLatin1String( "zip" ), Qt::CaseInsensitive ) == 0 ||
957  fileInfo.suffix().compare( QLatin1String( "tar" ), Qt::CaseInsensitive ) == 0 )
958  {
959  QgsDataItem *item = QgsZipItem::itemFromPath( this, path, name, mPath + '/' + name );
960  if ( item )
961  {
962  children.append( item );
963  continue;
964  }
965  }
966 
967  bool createdItem = false;
968  for ( QgsDataItemProvider *provider : providers )
969  {
970  int capabilities = provider->capabilities();
971 
972  if ( !( ( fileInfo.isFile() && ( capabilities & QgsDataProvider::File ) ) ||
973  ( fileInfo.isDir() && ( capabilities & QgsDataProvider::Dir ) ) ) )
974  {
975  continue;
976  }
977 
978  QgsDataItem *item = provider->createDataItem( path, this );
979  if ( item )
980  {
981  children.append( item );
982  createdItem = true;
983  }
984  }
985 
986  if ( !createdItem )
987  {
988  // if item is a QGIS project, and no specific item provider has overridden handling of
989  // project items, then use the default project item behavior
990  if ( fileInfo.suffix().compare( QLatin1String( "qgs" ), Qt::CaseInsensitive ) == 0 ||
991  fileInfo.suffix().compare( QLatin1String( "qgz" ), Qt::CaseInsensitive ) == 0 )
992  {
993  QgsDataItem *item = new QgsProjectItem( this, fileInfo.completeBaseName(), path );
994  children.append( item );
995  continue;
996  }
997  }
998 
999  }
1000  return children;
1001 }
1002 
1004 {
1006 
1007  if ( state == Populated )
1008  {
1009  if ( !mFileSystemWatcher )
1010  {
1011  mFileSystemWatcher = new QFileSystemWatcher( this );
1012  mFileSystemWatcher->addPath( mDirPath );
1013  connect( mFileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, &QgsDirectoryItem::directoryChanged );
1014  }
1015  mLastScan = QDateTime::currentDateTime();
1016  }
1017  else if ( state == NotPopulated )
1018  {
1019  if ( mFileSystemWatcher )
1020  {
1021  delete mFileSystemWatcher;
1022  mFileSystemWatcher = nullptr;
1023  }
1024  }
1025 }
1026 
1028 {
1029  // If the last scan was less than 10 seconds ago, skip this
1030  if ( mLastScan.msecsTo( QDateTime::currentDateTime() ) < QgsSettings().value( QStringLiteral( "browser/minscaninterval" ), 10000 ).toInt() )
1031  {
1032  return;
1033  }
1034  if ( state() == Populating )
1035  {
1036  // schedule to refresh later, because refresh() simply returns if Populating
1037  mRefreshLater = true;
1038  }
1039  else
1040  {
1041  // We definintely don't want the temporary files created by sqlite
1042  // to re-trigger a refresh in an infinite loop.
1043  disconnect( mFileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, &QgsDirectoryItem::directoryChanged );
1044  // QFileSystemWhatcher::directoryChanged is emitted when a
1045  // file is created and not when it is closed/flushed.
1046  //
1047  // Delay to give to OS the time to complete writing the file
1048  // this happens when a new file appears in the directory and
1049  // the item's children thread will try to open the file with
1050  // GDAL or OGR even if it is still being written.
1051  QTimer::singleShot( 100, this, [ = ] { refresh(); } );
1052  }
1053 }
1054 
1055 bool QgsDirectoryItem::hiddenPath( const QString &path )
1056 {
1057  QgsSettings settings;
1058  QStringList hiddenItems = settings.value( QStringLiteral( "browser/hiddenPaths" ),
1059  QStringList() ).toStringList();
1060  int idx = hiddenItems.indexOf( path );
1061  return ( idx > -1 );
1062 }
1063 
1065 {
1066  QgsDebugMsgLevel( QStringLiteral( "mRefreshLater = %1" ).arg( mRefreshLater ), 3 );
1067 
1068  if ( mRefreshLater )
1069  {
1070  QgsDebugMsgLevel( QStringLiteral( "directory changed during createChidren() -> refresh() again" ), 3 );
1071  mRefreshLater = false;
1072  setState( Populated );
1073  refresh();
1074  }
1075  else
1076  {
1078  }
1079  // Re-connect the file watcher after all children have been created
1080  connect( mFileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, &QgsDirectoryItem::directoryChanged );
1081 }
1082 
1084 {
1085  //QgsDebugMsg ( mPath + " x " + other->mPath );
1086  if ( type() != other->type() )
1087  {
1088  return false;
1089  }
1090  return ( path() == other->path() );
1091 }
1092 
1094 {
1095  return new QgsDirectoryParamWidget( mPath );
1096 }
1097 
1099 {
1101  u.layerType = QStringLiteral( "directory" );
1102  u.name = mName;
1103  u.uri = mDirPath;
1104  return u;
1105 }
1106 
1107 QgsDirectoryParamWidget::QgsDirectoryParamWidget( const QString &path, QWidget *parent )
1108  : QTreeWidget( parent )
1109 {
1110  setRootIsDecorated( false );
1111 
1112  // name, size, date, permissions, owner, group, type
1113  setColumnCount( 7 );
1114  QStringList labels;
1115  labels << tr( "Name" ) << tr( "Size" ) << tr( "Date" ) << tr( "Permissions" ) << tr( "Owner" ) << tr( "Group" ) << tr( "Type" );
1116  setHeaderLabels( labels );
1117 
1118  QIcon iconDirectory = QgsApplication::getThemeIcon( QStringLiteral( "mIconFolder.svg" ) );
1119  QIcon iconFile = QgsApplication::getThemeIcon( QStringLiteral( "mIconFile.svg" ) );
1120  QIcon iconDirLink = QgsApplication::getThemeIcon( QStringLiteral( "mIconFolderLink.svg" ) );
1121  QIcon iconFileLink = QgsApplication::getThemeIcon( QStringLiteral( "mIconFileLink.svg" ) );
1122 
1123  QList<QTreeWidgetItem *> items;
1124 
1125  QDir dir( path );
1126  QStringList entries = dir.entryList( QDir::AllEntries | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
1127  const auto constEntries = entries;
1128  for ( const QString &name : constEntries )
1129  {
1130  QFileInfo fi( dir.absoluteFilePath( name ) );
1131  QStringList texts;
1132  texts << name;
1133  QString size;
1134  if ( fi.size() > 1024 )
1135  {
1136  size = QStringLiteral( "%1 KiB" ).arg( QString::number( fi.size() / 1024.0, 'f', 1 ) );
1137  }
1138  else if ( fi.size() > 1.048576e6 )
1139  {
1140  size = QStringLiteral( "%1 MiB" ).arg( QString::number( fi.size() / 1.048576e6, 'f', 1 ) );
1141  }
1142  else
1143  {
1144  size = QStringLiteral( "%1 B" ).arg( fi.size() );
1145  }
1146  texts << size;
1147  texts << fi.lastModified().toString( Qt::SystemLocaleShortDate );
1148  QString perm;
1149  perm += fi.permission( QFile::ReadOwner ) ? 'r' : '-';
1150  perm += fi.permission( QFile::WriteOwner ) ? 'w' : '-';
1151  perm += fi.permission( QFile::ExeOwner ) ? 'x' : '-';
1152  // QFile::ReadUser, QFile::WriteUser, QFile::ExeUser
1153  perm += fi.permission( QFile::ReadGroup ) ? 'r' : '-';
1154  perm += fi.permission( QFile::WriteGroup ) ? 'w' : '-';
1155  perm += fi.permission( QFile::ExeGroup ) ? 'x' : '-';
1156  perm += fi.permission( QFile::ReadOther ) ? 'r' : '-';
1157  perm += fi.permission( QFile::WriteOther ) ? 'w' : '-';
1158  perm += fi.permission( QFile::ExeOther ) ? 'x' : '-';
1159  texts << perm;
1160 
1161  texts << fi.owner();
1162  texts << fi.group();
1163 
1164  QString type;
1165  QIcon icon;
1166  if ( fi.isDir() && fi.isSymLink() )
1167  {
1168  type = tr( "folder" );
1169  icon = iconDirLink;
1170  }
1171  else if ( fi.isDir() )
1172  {
1173  type = tr( "folder" );
1174  icon = iconDirectory;
1175  }
1176  else if ( fi.isFile() && fi.isSymLink() )
1177  {
1178  type = tr( "file" );
1179  icon = iconFileLink;
1180  }
1181  else if ( fi.isFile() )
1182  {
1183  type = tr( "file" );
1184  icon = iconFile;
1185  }
1186 
1187  texts << type;
1188 
1189  QTreeWidgetItem *item = new QTreeWidgetItem( texts );
1190  item->setIcon( 0, icon );
1191  items << item;
1192  }
1193 
1194  addTopLevelItems( items );
1195 
1196  // hide columns that are not requested
1197  QgsSettings settings;
1198  QList<QVariant> lst = settings.value( QStringLiteral( "dataitem/directoryHiddenColumns" ) ).toList();
1199  const auto constLst = lst;
1200  for ( const QVariant &colVariant : constLst )
1201  {
1202  setColumnHidden( colVariant.toInt(), true );
1203  }
1204 }
1205 
1207 {
1208  if ( event->button() == Qt::RightButton )
1209  {
1210  // show the popup menu
1211  QMenu popupMenu;
1212 
1213  QStringList labels;
1214  labels << tr( "Name" ) << tr( "Size" ) << tr( "Date" ) << tr( "Permissions" ) << tr( "Owner" ) << tr( "Group" ) << tr( "Type" );
1215  for ( int i = 0; i < labels.count(); i++ )
1216  {
1217  QAction *action = popupMenu.addAction( labels[i], this, &QgsDirectoryParamWidget::showHideColumn );
1218  action->setObjectName( QString::number( i ) );
1219  action->setCheckable( true );
1220  action->setChecked( !isColumnHidden( i ) );
1221  }
1222 
1223  popupMenu.exec( event->globalPos() );
1224  }
1225 }
1226 
1228 {
1229  QAction *action = qobject_cast<QAction *>( sender() );
1230  if ( !action )
1231  return; // something is wrong
1232 
1233  int columnIndex = action->objectName().toInt();
1234  setColumnHidden( columnIndex, !isColumnHidden( columnIndex ) );
1235 
1236  // save in settings
1237  QgsSettings settings;
1238  QList<QVariant> lst;
1239  for ( int i = 0; i < columnCount(); i++ )
1240  {
1241  if ( isColumnHidden( i ) )
1242  lst.append( QVariant( i ) );
1243  }
1244  settings.setValue( QStringLiteral( "dataitem/directoryHiddenColumns" ), lst );
1245 }
1246 
1247 QgsProjectItem::QgsProjectItem( QgsDataItem *parent, const QString &name,
1248  const QString &path, const QString &providerKey )
1249  : QgsDataItem( QgsDataItem::Project, parent, name, path, providerKey )
1250 {
1251  mIconName = QStringLiteral( ":/images/icons/qgis_icon.svg" );
1252  setToolTip( QDir::toNativeSeparators( path ) );
1253  setState( Populated ); // no more children
1254 }
1255 
1257 {
1259  u.layerType = QStringLiteral( "project" );
1260  u.name = mName;
1261  u.uri = mPath;
1262  return u;
1263 }
1264 
1265 QgsErrorItem::QgsErrorItem( QgsDataItem *parent, const QString &error, const QString &path )
1266  : QgsDataItem( QgsDataItem::Error, parent, error, path )
1267 {
1268  mIconName = QStringLiteral( "/mIconDelete.svg" );
1269 
1270  setState( Populated ); // no more children
1271 }
1272 
1273 QgsFavoritesItem::QgsFavoritesItem( QgsDataItem *parent, const QString &name, const QString &path )
1274  : QgsDataCollectionItem( parent, name, QStringLiteral( "favorites:" ), QStringLiteral( "special:Favorites" ) )
1275 {
1276  Q_UNUSED( path )
1277  mCapabilities |= Fast;
1278  mType = Favorites;
1279  mIconName = QStringLiteral( "/mIconFavourites.svg" );
1280  populate();
1281 }
1282 
1283 QVector<QgsDataItem *> QgsFavoritesItem::createChildren()
1284 {
1285  QVector<QgsDataItem *> children;
1286 
1287  QgsSettings settings;
1288  const QStringList favDirs = settings.value( QStringLiteral( "browser/favourites" ), QVariant() ).toStringList();
1289 
1290  for ( const QString &favDir : favDirs )
1291  {
1292  QStringList parts = favDir.split( QStringLiteral( "|||" ) );
1293  if ( parts.empty() )
1294  continue;
1295 
1296  QString dir = parts.at( 0 );
1297  QString name = dir;
1298  if ( parts.count() > 1 )
1299  name = parts.at( 1 );
1300 
1301  children << createChildren( dir, name );
1302  }
1303 
1304  return children;
1305 }
1306 
1307 void QgsFavoritesItem::addDirectory( const QString &favDir, const QString &n )
1308 {
1309  QString name = n.isEmpty() ? favDir : n;
1310 
1311  QgsSettings settings;
1312  QStringList favDirs = settings.value( QStringLiteral( "browser/favourites" ) ).toStringList();
1313  favDirs.append( QStringLiteral( "%1|||%2" ).arg( favDir, name ) );
1314  settings.setValue( QStringLiteral( "browser/favourites" ), favDirs );
1315 
1316  if ( state() == Populated )
1317  {
1318  QVector<QgsDataItem *> items = createChildren( favDir, name );
1319  const auto constItems = items;
1320  for ( QgsDataItem *item : constItems )
1321  {
1322  addChildItem( item, true );
1323  }
1324  }
1325 }
1326 
1328 {
1329  if ( !item )
1330  return;
1331 
1332  QgsSettings settings;
1333  QStringList favDirs = settings.value( QStringLiteral( "browser/favourites" ) ).toStringList();
1334  for ( int i = favDirs.count() - 1; i >= 0; --i )
1335  {
1336  QStringList parts = favDirs.at( i ).split( QStringLiteral( "|||" ) );
1337  if ( parts.empty() )
1338  continue;
1339 
1340  QString dir = parts.at( 0 );
1341  if ( dir == item->dirPath() )
1342  favDirs.removeAt( i );
1343  }
1344  settings.setValue( QStringLiteral( "browser/favourites" ), favDirs );
1345 
1346  int idx = findItem( mChildren, item );
1347  if ( idx < 0 )
1348  {
1349  QgsDebugMsg( QStringLiteral( "favorites item %1 not found" ).arg( item->path() ) );
1350  return;
1351  }
1352 
1353  if ( state() == Populated )
1354  deleteChildItem( mChildren.at( idx ) );
1355 }
1356 
1357 void QgsFavoritesItem::renameFavorite( const QString &path, const QString &name )
1358 {
1359  // update stored name
1360  QgsSettings settings;
1361  QStringList favDirs = settings.value( QStringLiteral( "browser/favourites" ) ).toStringList();
1362  for ( int i = 0; i < favDirs.count(); ++i )
1363  {
1364  QStringList parts = favDirs.at( i ).split( QStringLiteral( "|||" ) );
1365  if ( parts.empty() )
1366  continue;
1367 
1368  QString dir = parts.at( 0 );
1369  if ( dir == path )
1370  {
1371  favDirs[i] = QStringLiteral( "%1|||%2" ).arg( path, name );
1372  break;
1373  }
1374  }
1375  settings.setValue( QStringLiteral( "browser/favourites" ), favDirs );
1376 
1377  // also update existing data item
1378  const QVector<QgsDataItem *> ch = children();
1379  for ( QgsDataItem *child : ch )
1380  {
1381  if ( QgsFavoriteItem *favorite = qobject_cast< QgsFavoriteItem * >( child ) )
1382  {
1383  if ( favorite->dirPath() == path )
1384  {
1385  favorite->setName( name );
1386  break;
1387  }
1388  }
1389  }
1390 }
1391 
1392 QVector<QgsDataItem *> QgsFavoritesItem::createChildren( const QString &favDir, const QString &name )
1393 {
1394  QVector<QgsDataItem *> children;
1395  QString pathName = pathComponent( favDir );
1396  const auto constProviders = QgsApplication::dataItemProviderRegistry()->providers();
1397  for ( QgsDataItemProvider *provider : constProviders )
1398  {
1399  int capabilities = provider->capabilities();
1400 
1401  if ( capabilities & QgsDataProvider::Dir )
1402  {
1403  QgsDataItem *item = provider->createDataItem( favDir, this );
1404  if ( item )
1405  {
1406  item->setName( name );
1407  children.append( item );
1408  }
1409  }
1410  }
1411  if ( children.isEmpty() )
1412  {
1413  QgsFavoriteItem *item = new QgsFavoriteItem( this, name, favDir, mPath + '/' + pathName );
1414  if ( item )
1415  {
1416  children.append( item );
1417  }
1418  }
1419  return children;
1420 }
1421 
1422 //-----------------------------------------------------------------------
1423 QStringList QgsZipItem::sProviderNames = QStringList();
1424 
1425 
1426 QgsZipItem::QgsZipItem( QgsDataItem *parent, const QString &name, const QString &path )
1427  : QgsDataCollectionItem( parent, name, path )
1428 {
1429  mFilePath = path;
1430  init();
1431 }
1432 
1433 QgsZipItem::QgsZipItem( QgsDataItem *parent, const QString &name,
1434  const QString &filePath, const QString &path,
1435  const QString &providerKey )
1436  : QgsDataCollectionItem( parent, name, path, providerKey )
1437  , mFilePath( filePath )
1438 {
1439  init();
1440 }
1441 
1442 void QgsZipItem::init()
1443 {
1444  mType = Collection; //Zip??
1445  mIconName = QStringLiteral( "/mIconZip.svg" );
1447 
1448  static std::once_flag initialized;
1449  std::call_once( initialized, [ = ]
1450  {
1451  sProviderNames << QStringLiteral( "OGR" ) << QStringLiteral( "GDAL" );
1452  } );
1453 }
1454 
1455 QVector<QgsDataItem *> QgsZipItem::createChildren()
1456 {
1457  QVector<QgsDataItem *> children;
1458  QString tmpPath;
1459  QgsSettings settings;
1460  QString scanZipSetting = settings.value( QStringLiteral( "qgis/scanZipInBrowser2" ), "basic" ).toString();
1461 
1462  mZipFileList.clear();
1463 
1464  QgsDebugMsgLevel( QStringLiteral( "mFilePath = %1 path = %2 name= %3 scanZipSetting= %4 vsiPrefix= %5" ).arg( mFilePath, path(), name(), scanZipSetting, mVsiPrefix ), 3 );
1465 
1466  // if scanZipBrowser == no: skip to the next file
1467  if ( scanZipSetting == QLatin1String( "no" ) )
1468  {
1469  return children;
1470  }
1471 
1472  // first get list of files
1473  getZipFileList();
1474 
1475  const QList<QgsDataItemProvider *> providers = QgsApplication::dataItemProviderRegistry()->providers();
1476 
1477  // loop over files inside zip
1478  const auto constMZipFileList = mZipFileList;
1479  for ( const QString &fileName : constMZipFileList )
1480  {
1481  QFileInfo info( fileName );
1482  tmpPath = mVsiPrefix + mFilePath + '/' + fileName;
1483  QgsDebugMsgLevel( "tmpPath = " + tmpPath, 3 );
1484 
1485  for ( QgsDataItemProvider *provider : providers )
1486  {
1487  if ( !sProviderNames.contains( provider->name() ) )
1488  continue;
1489 
1490  // ugly hack to remove .dbf file if there is a .shp file
1491  if ( provider->name() == QStringLiteral( "OGR" ) )
1492  {
1493  if ( info.suffix().compare( QLatin1String( "dbf" ), Qt::CaseInsensitive ) == 0 )
1494  {
1495  if ( mZipFileList.indexOf( fileName.left( fileName.count() - 4 ) + ".shp" ) != -1 )
1496  continue;
1497  }
1498  if ( info.completeSuffix().compare( QLatin1String( "shp.xml" ), Qt::CaseInsensitive ) == 0 )
1499  {
1500  continue;
1501  }
1502  }
1503 
1504  QgsDebugMsgLevel( QStringLiteral( "trying to load item %1 with %2" ).arg( tmpPath, provider->name() ), 3 );
1505  QgsDataItem *item = provider->createDataItem( tmpPath, this );
1506  if ( item )
1507  {
1508  // the item comes with zipped file name, set the name to relative path within zip file
1509  item->setName( fileName );
1510  children.append( item );
1511  }
1512  else
1513  {
1514  QgsDebugMsgLevel( QStringLiteral( "not loaded item" ), 3 );
1515  }
1516  }
1517  }
1518 
1519  return children;
1520 }
1521 
1522 QgsDataItem *QgsZipItem::itemFromPath( QgsDataItem *parent, const QString &path, const QString &name )
1523 {
1524  return itemFromPath( parent, path, name, path );
1525 }
1526 
1527 QgsDataItem *QgsZipItem::itemFromPath( QgsDataItem *parent, const QString &filePath, const QString &name, const QString &path )
1528 {
1529  QgsSettings settings;
1530  QString scanZipSetting = settings.value( QStringLiteral( "qgis/scanZipInBrowser2" ), "basic" ).toString();
1531  QStringList zipFileList;
1532  QString vsiPrefix = QgsZipItem::vsiPrefix( filePath );
1533  QgsZipItem *zipItem = nullptr;
1534  bool populated = false;
1535 
1536  QgsDebugMsgLevel( QStringLiteral( "path = %1 name= %2 scanZipSetting= %3 vsiPrefix= %4" ).arg( path, name, scanZipSetting, vsiPrefix ), 3 );
1537 
1538  // don't scan if scanZipBrowser == no
1539  if ( scanZipSetting == QLatin1String( "no" ) )
1540  return nullptr;
1541 
1542  // don't scan if this file is not a /vsizip/ or /vsitar/ item
1543  if ( ( vsiPrefix != QLatin1String( "/vsizip/" ) && vsiPrefix != QLatin1String( "/vsitar/" ) ) )
1544  return nullptr;
1545 
1546  zipItem = new QgsZipItem( parent, name, filePath, path );
1547 
1548  if ( zipItem )
1549  {
1550  // force populate zipItem if it has less than 10 items and is not a .tgz or .tar.gz file (slow loading)
1551  // for other items populating will be delayed until item is opened
1552  // this might be polluting the tree with empty items but is necessary for performance reasons
1553  // could also accept all files smaller than a certain size and add options for file count and/or size
1554 
1555  // first get list of files inside .zip or .tar files
1556  if ( path.endsWith( QLatin1String( ".zip" ), Qt::CaseInsensitive ) ||
1557  path.endsWith( QLatin1String( ".tar" ), Qt::CaseInsensitive ) )
1558  {
1559  zipFileList = zipItem->getZipFileList();
1560  }
1561  // force populate if less than 10 items
1562  if ( !zipFileList.isEmpty() && zipFileList.count() <= 10 )
1563  {
1564  zipItem->populate( zipItem->createChildren() );
1565  populated = true; // there is no QgsDataItem::isPopulated() function
1566  QgsDebugMsgLevel( QStringLiteral( "Got zipItem with %1 children, path=%2, name=%3" ).arg( zipItem->rowCount() ).arg( zipItem->path(), zipItem->name() ), 3 );
1567  }
1568  else
1569  {
1570  QgsDebugMsgLevel( QStringLiteral( "Delaying populating zipItem with path=%1, name=%2" ).arg( zipItem->path(), zipItem->name() ), 3 );
1571  }
1572  }
1573 
1574  // only display if has children or if is not populated
1575  if ( zipItem && ( !populated || zipItem->rowCount() > 0 ) )
1576  {
1577  QgsDebugMsgLevel( QStringLiteral( "returning zipItem" ), 3 );
1578  return zipItem;
1579  }
1580 
1581  return nullptr;
1582 }
1583 
1585 {
1586  if ( ! mZipFileList.isEmpty() )
1587  return mZipFileList;
1588 
1589  QString tmpPath;
1590  QgsSettings settings;
1591  QString scanZipSetting = settings.value( QStringLiteral( "qgis/scanZipInBrowser2" ), "basic" ).toString();
1592 
1593  QgsDebugMsgLevel( QStringLiteral( "mFilePath = %1 name= %2 scanZipSetting= %3 vsiPrefix= %4" ).arg( mFilePath, name(), scanZipSetting, mVsiPrefix ), 3 );
1594 
1595  // if scanZipBrowser == no: skip to the next file
1596  if ( scanZipSetting == QLatin1String( "no" ) )
1597  {
1598  return mZipFileList;
1599  }
1600 
1601  // get list of files inside zip file
1602  QgsDebugMsgLevel( QStringLiteral( "Open file %1 with gdal vsi" ).arg( mVsiPrefix + mFilePath ), 3 );
1603  char **papszSiblingFiles = VSIReadDirRecursive( QString( mVsiPrefix + mFilePath ).toLocal8Bit().constData() );
1604  if ( papszSiblingFiles )
1605  {
1606  for ( int i = 0; papszSiblingFiles[i]; i++ )
1607  {
1608  tmpPath = papszSiblingFiles[i];
1609  QgsDebugMsgLevel( QStringLiteral( "Read file %1" ).arg( tmpPath ), 3 );
1610  // skip directories (files ending with /)
1611  if ( tmpPath.right( 1 ) != QLatin1String( "/" ) )
1612  mZipFileList << tmpPath;
1613  }
1614  CSLDestroy( papszSiblingFiles );
1615  }
1616  else
1617  {
1618  QgsDebugMsg( QStringLiteral( "Error reading %1" ).arg( mFilePath ) );
1619  }
1620 
1621  return mZipFileList;
1622 }
1623 
1625 
1626 QgsProjectHomeItem::QgsProjectHomeItem( QgsDataItem *parent, const QString &name, const QString &dirPath, const QString &path )
1627  : QgsDirectoryItem( parent, name, dirPath, path, QStringLiteral( "special:ProjectHome" ) )
1628 {
1629 }
1630 
1631 QIcon QgsProjectHomeItem::icon()
1632 {
1633  if ( state() == Populating )
1634  return QgsDirectoryItem::icon();
1635  return QgsApplication::getThemeIcon( QStringLiteral( "mIconFolderProject.svg" ) );
1636 }
1637 
1638 QVariant QgsProjectHomeItem::sortKey() const
1639 {
1640  return QStringLiteral( " 1" );
1641 }
1642 
1643 
1644 QgsFavoriteItem::QgsFavoriteItem( QgsFavoritesItem *parent, const QString &name, const QString &dirPath, const QString &path )
1645  : QgsDirectoryItem( parent, name, dirPath, path, QStringLiteral( "special:Favorites" ) )
1646  , mFavorites( parent )
1647 {
1648  mCapabilities |= Rename;
1649 }
1650 
1651 bool QgsFavoriteItem::rename( const QString &name )
1652 {
1653  mFavorites->renameFavorite( dirPath(), name );
1654  return true;
1655 }
1656 
1657 
QgsLayerItem::mapLayerType
QgsMapLayerType mapLayerType() const
Returns QgsMapLayerType.
Definition: qgsdataitem.cpp:642
QgsMimeDataUtils::Uri::wkbType
QgsWkbTypes::Type wkbType
WKB type, if associated with a vector layer, or QgsWkbTypes::Unknown if not yet known.
Definition: qgsmimedatautils.h:146
QgsZipItem::iconZip
static QIcon iconZip()
Definition: qgsdataitem.cpp:123
QgsLayerItem::TableLayer
@ TableLayer
Definition: qgsdataitem.h:512
QgsMimeDataUtils::Uri::name
QString name
Human readable name to be used e.g. in layer tree.
Definition: qgsmimedatautils.h:121
QgsMimeDataUtils::Uri::uri
QString uri
Identifier of the data source recognized by its providerKey.
Definition: qgsmimedatautils.h:123
QgsDataItem::mIconMap
QMap< QString, QIcon > mIconMap
Definition: qgsdataitem.h:420
QgsLayerItem::iconLine
static QIcon iconLine()
Definition: qgsdataitem.cpp:58
QgsLayerItem::Point
@ Point
Definition: qgsdataitem.h:509
QgsLayerItem::Mesh
@ Mesh
Added in 3.2.
Definition: qgsdataitem.h:516
QgsDataItem::icon
virtual QIcon icon()
Definition: qgsdataitem.cpp:233
QgsDataItem::rowCount
int rowCount()
Definition: qgsdataitem.cpp:459
QgsDataItem::mIcon
QIcon mIcon
Definition: qgsdataitem.h:419
QgsDataCollectionItem
Definition: qgsdataitem.h:618
QgsDataItem::Favorites
@ Favorites
Represents a favorite item.
Definition: qgsdataitem.h:82
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
Definition: qgsapplication.cpp:605
QgsWkbTypes::Point
@ Point
Definition: qgswkbtypes.h:71
QgsDirectoryItem::mimeUri
QgsMimeDataUtils::Uri mimeUri() const override
Returns mime URI for the data item.
Definition: qgsdataitem.cpp:1098
QgsDataItem::path
QString path() const
Definition: qgsdataitem.h:327
qgsdataitemproviderregistry.h
QgsMimeDataUtils::Uri::supportedFormats
QStringList supportedFormats
Definition: qgsmimedatautils.h:125
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:174
QgsMapLayerType::MeshLayer
@ MeshLayer
Added in 3.2.
QgsZipItem::mZipFileList
QStringList mZipFileList
Definition: qgsdataitem.h:862
QgsDirectoryItem::hiddenPath
static bool hiddenPath(const QString &path)
Check if the given path is hidden from the browser model.
Definition: qgsdataitem.cpp:1055
QgsLayerItem::mLayerType
LayerType mLayerType
The layer type.
Definition: qgsdataitem.h:591
QgsWkbTypes::NullGeometry
@ NullGeometry
Definition: qgswkbtypes.h:145
QgsMapLayerType::VectorLayer
@ VectorLayer
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsDataItem::mType
Type mType
Definition: qgsdataitem.h:405
QgsDataItem::capabilities2
virtual Capabilities capabilities2() const
Returns the capabilities for the data item.
Definition: qgsdataitem.h:283
QgsFavoritesItem::renameFavorite
void renameFavorite(const QString &path, const QString &name)
Renames the stored favorite with corresponding path a new name.
Definition: qgsdataitem.cpp:1357
QgsDataCollectionItem::iconDir
static QIcon iconDir()
Returns the standard browser directory icon.
Definition: qgsdataitem.cpp:108
QgsZipItem::mFilePath
QString mFilePath
Definition: qgsdataitem.h:860
QgsZipItem
Definition: qgsdataitem.h:855
QgsDataCollectionItem::iconDataCollection
static QIcon iconDataCollection()
Returns the standard browser data collection icon.
Definition: qgsdataitem.cpp:93
QgsLayerItem::iconDefault
static QIcon iconDefault()
Definition: qgsdataitem.cpp:88
QgsDataCollectionItem::~QgsDataCollectionItem
~QgsDataCollectionItem() override
Definition: qgsdataitem.cpp:829
QgsFavoritesItem::iconFavorites
static QIcon iconFavorites()
Icon for favorites group.
Definition: qgsdataitem.cpp:113
QgsMimeDataUtils::Uri::layerType
QString layerType
Type of URI.
Definition: qgsmimedatautils.h:110
QgsLayerItem::VectorTile
@ VectorTile
Added in 3.14.
Definition: qgsdataitem.h:517
QgsMapLayerType
QgsMapLayerType
Definition: qgsmaplayer.h:67
QgsDataItem::sortKey
virtual QVariant sortKey() const
Returns the sorting key for the item.
Definition: qgsdataitem.cpp:172
QgsWkbTypes::LineString
@ LineString
Definition: qgswkbtypes.h:72
QgsLayerItem::iconRaster
static QIcon iconRaster()
Definition: qgsdataitem.cpp:73
QgsDirectoryItem::createChildren
QVector< QgsDataItem * > createChildren() override
Create children.
Definition: qgsdataitem.cpp:896
qgsdataitem.h
QgsFavoritesItem::removeDirectory
void removeDirectory(QgsDirectoryItem *item)
Removes an existing directory from the favorites group.
Definition: qgsdataitem.cpp:1327
QgsLayerItem::NoType
@ NoType
Definition: qgsdataitem.h:506
QgsLayerItem::iconName
static QString iconName(LayerType layerType)
Returns the icon name of the given layerType.
Definition: qgsdataitem.cpp:717
QgsZipItem::getZipFileList
QStringList getZipFileList()
Definition: qgsdataitem.cpp:1584
QgsLayerItem::Vector
@ Vector
Definition: qgsdataitem.h:507
QgsDataItem::setProviderKey
void setProviderKey(const QString &value)
Sets the provider key that created this item (e.g.
Definition: qgsdataitem.cpp:454
qgis.h
QgsDataItem::QgsDataItem
QgsDataItem(QgsDataItem::Type type, QgsDataItem *parent, const QString &name, const QString &path, const QString &providerKey=QString())
Constructor for QgsDataItem, with the specified parent item.
Definition: qgsdataitem.cpp:130
QgsDataItem::setToolTip
void setToolTip(const QString &msg)
Definition: qgsdataitem.h:379
QgsZipItem::itemFromPath
static QgsDataItem * itemFromPath(QgsDataItem *parent, const QString &path, const QString &name)
Creates a new data item from the specified path.
Definition: qgsdataitem.cpp:1522
QgsDirectoryItem::icon
QIcon icon() override
Definition: qgsdataitem.cpp:871
QgsDataItem::name
QString name() const
Returns the name of the item (the displayed text for the item).
Definition: qgsdataitem.h:318
QgsSettings
Definition: qgssettings.h:61
QgsDataItem::dataChanged
void dataChanged(QgsDataItem *item)
QgsDataItem::deleteLater
static void deleteLater(QVector< QgsDataItem * > &items)
Definition: qgsdataitem.cpp:206
QgsDataItem::layerCollection
virtual bool layerCollection() const
Returns true if the data item is a collection of layers The default implementation returns false,...
Definition: qgsdataitem.cpp:468
QgsApplication::instance
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
Definition: qgsapplication.cpp:390
QgsDataItem::mSortKey
QVariant mSortKey
Custom sort key. If invalid, name() will be used for sorting instead.
Definition: qgsdataitem.h:423
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsDirectoryParamWidget::showHideColumn
void showHideColumn()
Definition: qgsdataitem.cpp:1227
QgsApplication::iconPath
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
Definition: qgsapplication.cpp:594
QgsDataItem::mIconName
QString mIconName
Definition: qgsdataitem.h:418
QgsDataItem::beginRemoveItems
void beginRemoveItems(QgsDataItem *parent, int first, int last)
QgsZipItem::createChildren
QVector< QgsDataItem * > createChildren() override
Create children.
Definition: qgsdataitem.cpp:1455
QgsDataItem::Directory
@ Directory
Definition: qgsdataitem.h:79
QgsDataItem::state
State state() const
Definition: qgsdataitem.cpp:589
QgsDataItem::equal
virtual bool equal(const QgsDataItem *other)
Returns true if this item is equal to another item (by testing item type and path).
Definition: qgsdataitem.cpp:567
QgsDataItem::Fertile
@ Fertile
Can create children. Even items without this capability may have children, but cannot create them,...
Definition: qgsdataitem.h:242
QgsDataItem::depopulate
virtual void depopulate()
Remove children recursively and set as not populated. This is used when refreshing collapsed items.
Definition: qgsdataitem.cpp:350
QgsFavoritesItem::addDirectory
void addDirectory(const QString &directory, const QString &name=QString())
Adds a new directory to the favorites group.
Definition: qgsdataitem.cpp:1307
QgsLayerItem::deleteLayer
virtual Q_DECL_DEPRECATED bool deleteLayer()
Delete this layer item Use QgsDataItemGuiProvider::deleteLayer instead.
Definition: qgsdataitem.cpp:742
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:143
QgsFavoritesItem::createChildren
QVector< QgsDataItem * > createChildren() override
Create children.
Definition: qgsdataitem.cpp:1283
QgsDataItem::pathComponent
static QString pathComponent(const QString &component)
Create path component replacing path separators.
Definition: qgsdataitem.cpp:167
QgsDirectoryItem::dirPath
QString dirPath() const
Returns the full path to the directory the item represents.
Definition: qgsdataitem.h:717
QgsDirectoryItem::equal
bool equal(const QgsDataItem *other) override
Returns true if this item is equal to another item (by testing item type and path).
Definition: qgsdataitem.cpp:1083
qgsapplication.h
QgsDataItem::refreshConnections
virtual void refreshConnections(const QString &providerKey=QString())
Causes a data item provider to refresh all registered connections.
Definition: qgsdataitem.cpp:387
QgsDataItem::mState
State mState
Definition: qgsdataitem.h:409
QgsDataItem::endRemoveItems
void endRemoveItems()
QgsZipItem::mVsiPrefix
QString mVsiPrefix
Definition: qgsdataitem.h:861
QgsDataItem::type
Type type() const
Definition: qgsdataitem.h:299
QgsDirectoryItem::paramWidget
Q_DECL_DEPRECATED QWidget * paramWidget() override
Returns source widget from data item for QgsBrowserPropertiesWidget.
Definition: qgsdataitem.cpp:1093
QgsDataItem::rename
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.
Definition: qgsdataitem.cpp:584
QgsProjectItem
Definition: qgsdataitem.h:746
qgsproviderregistry.h
QgsDirectoryItem
Definition: qgsdataitem.h:671
QgsLayerItem::Database
@ Database
Definition: qgsdataitem.h:513
QgsLayerItem::iconPoint
static QIcon iconPoint()
Definition: qgsdataitem.cpp:53
QgsDataItem::parent
QgsDataItem * parent() const
Gets item parent.
Definition: qgsdataitem.h:304
QgsLayerItem::Line
@ Line
Definition: qgsdataitem.h:510
QgsDirectoryItem::init
void init()
Definition: qgsdataitem.cpp:866
QgsAnimatedIcon::connectFrameChanged
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...
Definition: qgsanimatedicon.h:85
QgsDataItemProviderRegistry::providers
QList< QgsDataItemProvider * > providers() const
Returns the list of available providers.
Definition: qgsdataitemproviderregistry.cpp:48
QgsDataItemProvider
Definition: qgsdataitemprovider.h:45
QgsDataCollectionItem::openDirIcon
static QIcon openDirIcon()
Shared open directory icon.
Definition: qgsdataitem.cpp:98
QgsLayerItem::iconVectorTile
static QIcon iconVectorTile()
Returns icon for vector tile layer.
Definition: qgsdataitem.cpp:83
QgsMapLayerType::RasterLayer
@ RasterLayer
QgsAnimatedIcon::icon
QIcon icon() const
Gets the icons representation in the current frame.
Definition: qgsanimatedicon.cpp:41
QgsDataItem::Rename
@ Rename
Item can be renamed.
Definition: qgsdataitem.h:245
QgsApplication::dataItemProviderRegistry
static QgsDataItemProviderRegistry * dataItemProviderRegistry()
Returns the application's data item provider registry, which keeps a list of data item providers that...
Definition: qgsapplication.cpp:2109
QgsDataCollectionItem::QgsDataCollectionItem
QgsDataCollectionItem(QgsDataItem *parent, const QString &name, const QString &path=QString(), const QString &providerKey=QString())
Constructor for QgsDataCollectionItem, with the specified parent item.
Definition: qgsdataitem.cpp:819
QgsDirectoryParamWidget::QgsDirectoryParamWidget
QgsDirectoryParamWidget(const QString &path, QWidget *parent=nullptr)
Definition: qgsdataitem.cpp:1107
QgsLayerItem::mUri
QString mUri
The URI.
Definition: qgsdataitem.h:589
QgsDirectoryItem::childrenCreated
void childrenCreated() override
Definition: qgsdataitem.cpp:1064
QgsDataItem::handleDoubleClick
virtual bool handleDoubleClick()
Called when a user double clicks on the item.
Definition: qgsdataitem.cpp:579
QgsDataItem::Collection
@ Collection
Definition: qgsdataitem.h:78
QgsAnimatedIcon::disconnectFrameChanged
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.
Definition: qgsanimatedicon.h:104
QgsDataItem::Populating
@ Populating
Creating children in separate thread (populating or refreshing)
Definition: qgsdataitem.h:123
QgsSettings::setValue
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Definition: qgssettings.cpp:289
QgsDataItem::mName
QString mName
Definition: qgsdataitem.h:410
QgsDataItem::Type
Type
Definition: qgsdataitem.h:76
QgsMimeDataUtils::Uri
Definition: qgsmimedatautils.h:40
QgsMimeDataUtils::Uri::supportedCrs
QStringList supportedCrs
Definition: qgsmimedatautils.h:124
QgsDataItem::NotPopulated
@ NotPopulated
Children not yet created.
Definition: qgsdataitem.h:122
QgsLayerItem::Polygon
@ Polygon
Definition: qgsdataitem.h:511
QgsAnimatedIcon
Definition: qgsanimatedicon.h:30
QgsDataItem::connectionsChanged
void connectionsChanged(const QString &providerKey=QString())
Emitted when the connections of the provider with the specified providerKey have changed.
QgsLayerItem::iconTable
static QIcon iconTable()
Definition: qgsdataitem.cpp:68
QgsZipItem::vsiPrefix
static QString vsiPrefix(const QString &uri)
Definition: qgsdataitem.h:878
QgsLayerItem::iconPolygon
static QIcon iconPolygon()
Definition: qgsdataitem.cpp:63
QgsDataItem::moveToThread
void moveToThread(QThread *targetThread)
Move object and all its descendants to thread.
Definition: qgsdataitem.cpp:218
QgsDataProvider::File
@ File
Definition: qgsdataprovider.h:76
QgsDataItem::actions
virtual QList< QAction * > actions(QWidget *parent)
Returns the list of actions available for this item.
Definition: qgsdataitem.cpp:573
QgsDirectoryItem::mDirPath
QString mDirPath
Definition: qgsdataitem.h:734
QgsDataItem::endInsertItems
void endInsertItems()
QgsMimeDataUtils::Uri::providerKey
QString providerKey
For "vector" / "raster" type: provider id.
Definition: qgsmimedatautils.h:118
qgsvectorlayer.h
QgsDirectoryItem::setState
void setState(State state) override
Set item state.
Definition: qgsdataitem.cpp:1003
QgsDataItem::updateIcon
void updateIcon()
Will request a repaint of this icon.
Definition: qgsdataitem.cpp:330
QgsDirectoryParamWidget::mousePressEvent
void mousePressEvent(QMouseEvent *event) override
Definition: qgsdataitem.cpp:1206
QgsLayerItem::Plugin
@ Plugin
Added in 2.10.
Definition: qgsdataitem.h:515
qgsdataitemprovider.h
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:142
QgsDataItem::hasChildren
bool hasChildren()
Definition: qgsdataitem.cpp:463
QgsLayerItem::typeFromMapLayer
static LayerType typeFromMapLayer(QgsMapLayer *layer)
Returns the layer item type corresponding to a QgsMapLayer layer.
Definition: qgsdataitem.cpp:672
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:141
QgsDataItem::mCapabilities
Capabilities mCapabilities
Definition: qgsdataitem.h:406
QgsDataItem::addChildItem
virtual void addChildItem(QgsDataItem *child, bool refresh=false)
Inserts a new child item.
Definition: qgsdataitem.cpp:491
QgsFavoritesItem::QgsFavoritesItem
QgsFavoritesItem(QgsDataItem *parent, const QString &name, const QString &path=QString())
Constructor for QgsFavoritesItem.
Definition: qgsdataitem.cpp:1273
QgsDataItem::setName
void setName(const QString &name)
Sets the name of the item (the displayed text for the item).
Definition: qgsdataitem.cpp:249
QgsWkbTypes::NoGeometry
@ NoGeometry
Definition: qgswkbtypes.h:84
QgsDataProvider::Dir
@ Dir
Definition: qgsdataprovider.h:77
QgsDataItem::mPath
QString mPath
Definition: qgsdataitem.h:416
QgsLayerItem::iconMesh
static QIcon iconMesh()
Returns icon for mesh layer type.
Definition: qgsdataitem.cpp:78
QgsLayerItem::QgsLayerItem
QgsLayerItem(QgsDataItem *parent, const QString &name, const QString &path, const QString &uri, LayerType layerType, const QString &providerKey)
Definition: qgsdataitem.cpp:633
QgsZipItem::QgsZipItem
QgsZipItem(QgsDataItem *parent, const QString &name, const QString &path)
Constructor.
Definition: qgsdataitem.cpp:1426
QgsDataItem::mProviderKey
QString mProviderKey
Definition: qgsdataitem.h:411
QgsDataItem::~QgsDataItem
~QgsDataItem() override
Definition: qgsdataitem.cpp:144
QgsDataItem::mParent
QgsDataItem * mParent
Definition: qgsdataitem.h:407
QgsMapLayer
Definition: qgsmaplayer.h:81
QgsWkbTypes::Polygon
@ Polygon
Definition: qgswkbtypes.h:73
QgsDirectoryItem::directoryChanged
void directoryChanged()
Definition: qgsdataitem.cpp:1027
QgsDataItem::populate
virtual void populate(const QVector< QgsDataItem * > &children)
Definition: qgsdataitem.cpp:335
qgssettings.h
QgsDataItem::mChildren
QVector< QgsDataItem * > mChildren
Definition: qgsdataitem.h:408
qgsanimatedicon.h
QgsMapLayerType::VectorTileLayer
@ VectorTileLayer
Added in 3.14.
QgsProjectItem::QgsProjectItem
QgsProjectItem(QgsDataItem *parent, const QString &name, const QString &path, const QString &providerKey=QString())
A data item holding a reference to a QGIS project file.
Definition: qgsdataitem.cpp:1247
QgsLayerItem::equal
bool equal(const QgsDataItem *other) override
Returns true if this item is equal to another item (by testing item type and path).
Definition: qgsdataitem.cpp:747
QgsWkbTypes::UnknownGeometry
@ UnknownGeometry
Definition: qgswkbtypes.h:144
QgsDataItem::setState
virtual void setState(State state)
Set item state.
Definition: qgsdataitem.cpp:594
QgsLayerItem::supportedCrs
QStringList supportedCrs() const
Returns the supported CRS.
Definition: qgsdataitem.h:553
QgsDataItem::children
QVector< QgsDataItem * > children() const
Definition: qgsdataitem.h:310
qgsdataprovider.h
QgsLayerItem
Definition: qgsdataitem.h:499
QgsDataItem::Populated
@ Populated
Children created.
Definition: qgsdataitem.h:124
QgsDirectoryParamWidget
Definition: qgsdataitem.h:789
QgsDataItem::Fast
@ Fast
CreateChildren() is fast enough to be run in main thread when refreshing items, most root items (wms,...
Definition: qgsdataitem.h:243
QgsDataItem::deferredDelete
bool deferredDelete()
The item is scheduled to be deleted.
Definition: qgsdataitem.h:403
QgsDataItem::findItem
static int findItem(QVector< QgsDataItem * > items, QgsDataItem *item)
Definition: qgsdataitem.cpp:555
QgsZipItem::sProviderNames
static QStringList sProviderNames
Definition: qgsdataitem.h:876
QgsLayerItem::Table
@ Table
Definition: qgsdataitem.h:514
QgsDirectoryItem::QgsDirectoryItem
QgsDirectoryItem(QgsDataItem *parent, const QString &name, const QString &path)
Constructor for QgsDirectoryItem, with the specified parent item.
Definition: qgsdataitem.cpp:846
QgsDataItem::menus
virtual QList< QMenu * > menus(QWidget *parent)
Returns the list of menus available for this item.
Definition: qgsdataitem.cpp:625
QgsLayerItem::providerKey
QString providerKey() const
Returns provider key.
Definition: qgsdataitem.h:547
qgslogger.h
QgsDataItem::deleteLater
virtual void deleteLater()
Safely delete the item:
Definition: qgsdataitem.cpp:182
QgsDataItem::providerKey
QString providerKey() const
Returns the provider key that created this item (e.g.
Definition: qgsdataitem.cpp:449
QgsFavoritesItem
Definition: qgsdataitem.h:808
QgsFavoritesItem::sortKey
QVariant sortKey() const override
Returns the sorting key for the item.
Definition: qgsdataitem.cpp:118
QgsLayerItem::layerName
virtual QString layerName() const
Definition: qgsdataitem.h:610
QgsDataItem::removeChildItem
virtual QgsDataItem * removeChildItem(QgsDataItem *child)
Removes a child item and returns it without deleting it.
Definition: qgsdataitem.cpp:538
QgsDataItem
Definition: qgsdataitem.h:49
QgsLayerItem::supportedFormats
QStringList supportedFormats() const
Returns the supported formats.
Definition: qgsdataitem.h:559
QgsDataItem::deleteChildItem
virtual void deleteChildItem(QgsDataItem *child)
Removes and deletes a child item, emitting relevant signals to the model.
Definition: qgsdataitem.cpp:527
QgsDataCollectionItem::homeDirIcon
static QIcon homeDirIcon()
Shared home directory icon.
Definition: qgsdataitem.cpp:103
QgsDataItem::stateChanged
void stateChanged(QgsDataItem *item, QgsDataItem::State oldState)
QgsDataItem::refresh
virtual void refresh()
Definition: qgsdataitem.cpp:364
QgsDataItem::setSortKey
void setSortKey(const QVariant &key)
Sets a custom sorting key for the item.
Definition: qgsdataitem.cpp:177
QgsDataItem::setParent
void setParent(QgsDataItem *parent)
Set item parent and connect / disconnect parent to / from item signals.
Definition: qgsdataitem.cpp:473
QgsErrorItem::QgsErrorItem
QgsErrorItem(QgsDataItem *parent, const QString &error, const QString &path)
Definition: qgsdataitem.cpp:1265
QgsMapLayer::type
QgsMapLayerType type() const
Returns the type of the layer.
Definition: qgsmaplayer.cpp:129
QgsDataItem::State
State
Definition: qgsdataitem.h:120
qgsproject.h
QgsMapLayerType::PluginLayer
@ PluginLayer
QgsLayerItem::mimeUri
QgsMimeDataUtils::Uri mimeUri() const override
Returns mime URI for the data item.
Definition: qgsdataitem.cpp:762
QgsProjectItem::mimeUri
QgsMimeDataUtils::Uri mimeUri() const override
Returns mime URI for the data item.
Definition: qgsdataitem.cpp:1256
QgsLayerItem::layerTypeAsString
static QString layerTypeAsString(LayerType layerType)
Returns the string representation of the given layerType.
Definition: qgsdataitem.cpp:711
QgsDataItem::createChildren
virtual QVector< QgsDataItem * > createChildren()
Create children.
Definition: qgsdataitem.cpp:255
QgsDataItem::beginInsertItems
void beginInsertItems(QgsDataItem *parent, int first, int last)
QgsLayerItem::LayerType
LayerType
Definition: qgsdataitem.h:504
QgsLayerItem::Raster
@ Raster
Definition: qgsdataitem.h:508
QgsLayerItem::uri
QString uri() const
Returns layer uri or empty string if layer cannot be created.
Definition: qgsdataitem.h:544
QgsDataItem::childrenCreated
virtual void childrenCreated()
Definition: qgsdataitem.cpp:307