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