QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgsbrowsermodel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsbrowsermodel.cpp
3  ---------------------
4  begin : July 2011
5  copyright : (C) 2011 by Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 #include <QDir>
16 #include <QApplication>
17 #include <QStyle>
18 #include <QtConcurrentMap>
19 #include <QUrl>
20 
21 #include "qgis.h"
22 #include "qgsapplication.h"
23 #include "qgsdataitemprovider.h"
25 #include "qgsdataprovider.h"
26 #include "qgsmimedatautils.h"
27 #include "qgslogger.h"
28 #include "qgsproviderregistry.h"
29 #include "qgsbrowsermodel.h"
30 #include "qgsproject.h"
31 #include "qgssettings.h"
32 
33 #define PROJECT_HOME_PREFIX "project:"
34 #define HOME_PREFIX "home:"
35 
37  : QFutureWatcher( nullptr )
38  , mItem( item )
39 {
40 }
41 
42 // sort function for QList<QgsDataItem*>, e.g. sorted/grouped provider listings
43 static bool cmpByDataItemName_( QgsDataItem *a, QgsDataItem *b )
44 {
45  return QString::localeAwareCompare( a->name(), b->name() ) < 0;
46 }
47 
49  : QAbstractItemModel( parent )
50 
51 {
52 }
53 
55 {
57 }
58 
60 {
61  QString home = QgsProject::instance()->homePath();
62  if ( mProjectHome && mProjectHome->path().mid( QStringLiteral( PROJECT_HOME_PREFIX ).length() ) == home )
63  return;
64 
65  int idx = mRootItems.indexOf( mProjectHome );
66 
67  // using layoutAboutToBeChanged() was messing expanded items
68  if ( idx >= 0 )
69  {
70  beginRemoveRows( QModelIndex(), idx, idx );
71  mRootItems.remove( idx );
72  endRemoveRows();
73  }
74  delete mProjectHome;
75  mProjectHome = home.isNull() ? nullptr : new QgsProjectHomeItem( nullptr, tr( "Project Home" ), home, QStringLiteral( PROJECT_HOME_PREFIX ) + home );
76  if ( mProjectHome )
77  {
78  setupItemConnections( mProjectHome );
79 
80  beginInsertRows( QModelIndex(), 0, 0 );
81  mRootItems.insert( 0, mProjectHome );
82  endInsertRows();
83  }
84 }
85 
87 {
89 
90  // give the home directory a prominent third place
91  QgsDirectoryItem *item = new QgsDirectoryItem( nullptr, tr( "Home" ), QDir::homePath(), QStringLiteral( HOME_PREFIX ) + QDir::homePath() );
92  item->setSortKey( QStringLiteral( " 2" ) );
93  setupItemConnections( item );
94  mRootItems << item;
95 
96  // add favorite directories
97  mFavorites = new QgsFavoritesItem( nullptr, tr( "Favorites" ) );
98  if ( mFavorites )
99  {
100  setupItemConnections( mFavorites );
102  }
103 
104  // add drives
105  Q_FOREACH ( const QFileInfo &drive, QDir::drives() )
106  {
107  const QString path = drive.absolutePath();
108 
109  if ( QgsDirectoryItem::hiddenPath( path ) )
110  continue;
111 
112  QgsDirectoryItem *item = new QgsDirectoryItem( nullptr, path, path );
113  item->setSortKey( QStringLiteral( " 3 %1" ).arg( path ) );
114  mDriveItems.insert( path, item );
115 
116  setupItemConnections( item );
117  mRootItems << item;
118  }
119 
120 #ifdef Q_OS_MAC
121  QString path = QString( "/Volumes" );
122  QgsDirectoryItem *vols = new QgsDirectoryItem( nullptr, path, path );
123  mRootItems << vols;
124 #endif
125 
126  // container for displaying providers as sorted groups (by QgsDataProvider::DataCapability enum)
127  QMap<int, QgsDataItem *> providerMap;
128 
129  Q_FOREACH ( QgsDataItemProvider *pr, QgsApplication::dataItemProviderRegistry()->providers() )
130  {
131  int capabilities = pr->capabilities();
132  if ( capabilities == QgsDataProvider::NoDataCapabilities )
133  {
134  QgsDebugMsgLevel( pr->name() + " does not have any dataCapabilities", 4 );
135  continue;
136  }
137 
138  QgsDataItem *item = pr->createDataItem( QString(), nullptr ); // empty path -> top level
139  if ( item )
140  {
141  // Forward the signal from the root items to the model (and then to the app)
143  QgsDebugMsgLevel( "Add new top level item : " + item->name(), 4 );
144  setupItemConnections( item );
145  providerMap.insertMulti( capabilities, item );
146  }
147  }
148 
149  // add as sorted groups by QgsDataProvider::DataCapability enum
150  Q_FOREACH ( int key, providerMap.uniqueKeys() )
151  {
152  QList<QgsDataItem *> providerGroup = providerMap.values( key );
153  if ( providerGroup.size() > 1 )
154  {
155  std::sort( providerGroup.begin(), providerGroup.end(), cmpByDataItemName_ );
156  }
157 
158  Q_FOREACH ( QgsDataItem *ditem, providerGroup )
159  {
160  mRootItems << ditem;
161  }
162  }
163 }
164 
166 {
167  Q_FOREACH ( QgsDataItem *item, mRootItems )
168  {
169  delete item;
170  }
171 
172  mRootItems.clear();
173  mDriveItems.clear();
174 }
175 
177 {
178  if ( ! mInitialized )
179  {
183  addRootItems();
184  mInitialized = true;
185  }
186 }
187 
188 
189 Qt::ItemFlags QgsBrowserModel::flags( const QModelIndex &index ) const
190 {
191  if ( !index.isValid() )
192  return Qt::ItemFlags();
193 
194  Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
195 
196  QgsDataItem *ptr = dataItem( index );
197 
198  if ( !ptr )
199  {
200  QgsDebugMsgLevel( QStringLiteral( "FLAGS PROBLEM!" ), 4 );
201  return Qt::ItemFlags();
202  }
203 
204  if ( ptr->hasDragEnabled() )
205  flags |= Qt::ItemIsDragEnabled;
206 
207  if ( ptr->acceptDrop() )
208  flags |= Qt::ItemIsDropEnabled;
209 
210  if ( ptr->capabilities2() & QgsDataItem::Rename )
211  flags |= Qt::ItemIsEditable;
212 
213  return flags;
214 }
215 
216 QVariant QgsBrowserModel::data( const QModelIndex &index, int role ) const
217 {
218  if ( !index.isValid() )
219  return QVariant();
220 
221  QgsDataItem *item = dataItem( index );
222  if ( !item )
223  {
224  return QVariant();
225  }
226  else if ( role == Qt::DisplayRole || role == Qt::EditRole )
227  {
228  return item->name();
229  }
230  else if ( role == QgsBrowserModel::SortRole )
231  {
232  return item->sortKey();
233  }
234  else if ( role == Qt::ToolTipRole )
235  {
236  return item->toolTip();
237  }
238  else if ( role == Qt::DecorationRole && index.column() == 0 )
239  {
240  return item->icon();
241  }
242  else if ( role == QgsBrowserModel::PathRole )
243  {
244  return item->path();
245  }
246  else if ( role == QgsBrowserModel::CommentRole )
247  {
248  if ( item->type() == QgsDataItem::Layer )
249  {
250  QgsLayerItem *lyrItem = qobject_cast<QgsLayerItem *>( item );
251  return lyrItem->comments();
252  }
253  return QVariant();
254  }
255  else
256  {
257  // unsupported role
258  return QVariant();
259  }
260 }
261 
262 bool QgsBrowserModel::setData( const QModelIndex &index, const QVariant &value, int role )
263 {
264  if ( !index.isValid() )
265  return false;
266 
267 
268  QgsDataItem *item = dataItem( index );
269  if ( !item )
270  {
271  return false;
272  }
273 
274  if ( !( item->capabilities2() & QgsDataItem::Rename ) )
275  return false;
276 
277  switch ( role )
278  {
279  case Qt::EditRole:
280  {
281  return item->rename( value.toString() );
282  }
283  }
284  return false;
285 }
286 
287 QVariant QgsBrowserModel::headerData( int section, Qt::Orientation orientation, int role ) const
288 {
289  Q_UNUSED( section );
290  if ( orientation == Qt::Horizontal && role == Qt::DisplayRole )
291  {
292  return QVariant( "header" );
293  }
294 
295  return QVariant();
296 }
297 
298 int QgsBrowserModel::rowCount( const QModelIndex &parent ) const
299 {
300  //QgsDebugMsg(QString("isValid = %1 row = %2 column = %3").arg(parent.isValid()).arg(parent.row()).arg(parent.column()));
301 
302  if ( !parent.isValid() )
303  {
304  // root item: its children are top level items
305  return mRootItems.count(); // mRoot
306  }
307  else
308  {
309  // ordinary item: number of its children
310  QgsDataItem *item = dataItem( parent );
311  //if ( item ) QgsDebugMsg(QString("path = %1 rowCount = %2").arg(item->path()).arg(item->rowCount()) );
312  return item ? item->rowCount() : 0;
313  }
314 }
315 
316 bool QgsBrowserModel::hasChildren( const QModelIndex &parent ) const
317 {
318  if ( !parent.isValid() )
319  return !mRootItems.isEmpty(); // root item: its children are top level items
320 
321  QgsDataItem *item = dataItem( parent );
322  return item && item->hasChildren();
323 }
324 
325 int QgsBrowserModel::columnCount( const QModelIndex &parent ) const
326 {
327  Q_UNUSED( parent );
328  return 1;
329 }
330 
331 QModelIndex QgsBrowserModel::findPath( const QString &path, Qt::MatchFlag matchFlag )
332 {
333  return findPath( this, path, matchFlag );
334 }
335 
336 QModelIndex QgsBrowserModel::findPath( QAbstractItemModel *model, const QString &path, Qt::MatchFlag matchFlag )
337 {
338  if ( !model )
339  return QModelIndex();
340 
341  QModelIndex index; // starting from root
342  bool foundChild = true;
343 
344  while ( foundChild )
345  {
346  foundChild = false; // assume that the next child item will not be found
347 
348  for ( int i = 0; i < model->rowCount( index ); i++ )
349  {
350  QModelIndex idx = model->index( i, 0, index );
351 
352  QString itemPath = model->data( idx, PathRole ).toString();
353  if ( itemPath == path )
354  {
355  QgsDebugMsgLevel( "Arrived " + itemPath, 4 );
356  return idx; // we have found the item we have been looking for
357  }
358 
359  // paths are slash separated identifier
360  if ( path.startsWith( itemPath + '/' ) )
361  {
362  foundChild = true;
363  index = idx;
364  break;
365  }
366  }
367  }
368 
369  if ( matchFlag == Qt::MatchStartsWith )
370  return index;
371 
372  QgsDebugMsgLevel( QStringLiteral( "path not found" ), 4 );
373  return QModelIndex(); // not found
374 }
375 
377 {
378  // deprecated, no use
379 }
380 
382 {
383  // TODO: put items creating currently children in threads to deleteLater (does not seem urget because reload() is not used in QGIS)
384  beginResetModel();
385  removeRootItems();
386  addRootItems();
387  endResetModel();
388 }
389 
391 {
392  const QList< QFileInfo > drives = QDir::drives();
393  // remove any removed drives
394  const QStringList existingDrives = mDriveItems.keys();
395  for ( const QString &drivePath : existingDrives )
396  {
397  bool stillExists = false;
398  for ( const QFileInfo &drive : drives )
399  {
400  if ( drivePath == drive.absolutePath() )
401  {
402  stillExists = true;
403  break;
404  }
405  }
406 
407  if ( stillExists )
408  continue;
409 
410  // drive has been removed, remove corresponding item
411  if ( QgsDataItem *driveItem = mDriveItems.value( drivePath ) )
412  removeRootItem( driveItem );
413  }
414 
415  for ( const QFileInfo &drive : drives )
416  {
417  const QString path = drive.absolutePath();
418 
419  if ( QgsDirectoryItem::hiddenPath( path ) )
420  continue;
421 
422  // does an item for this drive already exist?
423  if ( !mDriveItems.contains( path ) )
424  {
425  QgsDirectoryItem *item = new QgsDirectoryItem( nullptr, path, path );
426  item->setSortKey( QStringLiteral( " 3 %1" ).arg( path ) );
427 
428  mDriveItems.insert( path, item );
429  setupItemConnections( item );
430 
431  beginInsertRows( QModelIndex(), mRootItems.count(), mRootItems.count() );
432  mRootItems << item;
433  endInsertRows();
434  }
435  }
436 }
437 
438 QModelIndex QgsBrowserModel::index( int row, int column, const QModelIndex &parent ) const
439 {
440  if ( column < 0 || column >= columnCount() || row < 0 )
441  return QModelIndex();
442 
443  QgsDataItem *p = dataItem( parent );
444  const QVector<QgsDataItem *> &items = p ? p->children() : mRootItems;
445  QgsDataItem *item = items.value( row, nullptr );
446  return item ? createIndex( row, column, item ) : QModelIndex();
447 }
448 
449 QModelIndex QgsBrowserModel::parent( const QModelIndex &index ) const
450 {
451  QgsDataItem *item = dataItem( index );
452  if ( !item )
453  return QModelIndex();
454 
455  return findItem( item->parent() );
456 }
457 
459 {
460  const QVector<QgsDataItem *> &items = parent ? parent->children() : mRootItems;
461 
462  for ( int i = 0; i < items.size(); i++ )
463  {
464  if ( items[i] == item )
465  return createIndex( i, 0, item );
466 
467  QModelIndex childIndex = findItem( item, items[i] );
468  if ( childIndex.isValid() )
469  return childIndex;
470  }
471 
472  return QModelIndex();
473 }
474 
476 {
477  QgsDebugMsgLevel( "parent mPath = " + parent->path(), 3 );
478  QModelIndex idx = findItem( parent );
479  if ( !idx.isValid() )
480  return;
481  QgsDebugMsgLevel( QStringLiteral( "valid" ), 3 );
482  beginInsertRows( idx, first, last );
483  QgsDebugMsgLevel( QStringLiteral( "end" ), 3 );
484 }
486 {
487  QgsDebugMsgLevel( QStringLiteral( "Entered" ), 3 );
488  endInsertRows();
489 }
491 {
492  QgsDebugMsgLevel( "parent mPath = " + parent->path(), 3 );
493  QModelIndex idx = findItem( parent );
494  if ( !idx.isValid() )
495  return;
496  beginRemoveRows( idx, first, last );
497 }
499 {
500  QgsDebugMsgLevel( QStringLiteral( "Entered" ), 3 );
501  endRemoveRows();
502 }
504 {
505  QgsDebugMsgLevel( QStringLiteral( "Entered" ), 3 );
506  QModelIndex idx = findItem( item );
507  if ( !idx.isValid() )
508  return;
509  emit dataChanged( idx, idx );
510 }
512 {
513  if ( !item )
514  return;
515  QModelIndex idx = findItem( item );
516  if ( !idx.isValid() )
517  return;
518  QgsDebugMsgLevel( QStringLiteral( "item %1 state changed %2 -> %3" ).arg( item->path() ).arg( oldState ).arg( item->state() ), 4 );
519  emit stateChanged( idx, oldState );
520 }
521 
522 void QgsBrowserModel::setupItemConnections( QgsDataItem *item )
523 {
524  connect( item, &QgsDataItem::beginInsertItems,
526  connect( item, &QgsDataItem::endInsertItems,
528  connect( item, &QgsDataItem::beginRemoveItems,
530  connect( item, &QgsDataItem::endRemoveItems,
532  connect( item, &QgsDataItem::dataChanged,
534  connect( item, &QgsDataItem::stateChanged,
536 
537  // if it's a collection item, also forwards connectionsChanged
538  QgsDataCollectionItem *collectionItem = dynamic_cast<QgsDataCollectionItem *>( item );
539  if ( collectionItem )
541 }
542 
543 QStringList QgsBrowserModel::mimeTypes() const
544 {
545  QStringList types;
546  // In theory the mime type convention is: application/x-vnd.<vendor>.<application>.<type>
547  // but it seems a bit over formalized. Would be an application/x-qgis-uri better?
548  types << QStringLiteral( "application/x-vnd.qgis.qgis.uri" );
549  return types;
550 }
551 
552 QMimeData *QgsBrowserModel::mimeData( const QModelIndexList &indexes ) const
553 {
555  Q_FOREACH ( const QModelIndex &index, indexes )
556  {
557  if ( index.isValid() )
558  {
559  QgsDataItem *ptr = reinterpret_cast< QgsDataItem * >( index.internalPointer() );
560  QgsMimeDataUtils::Uri uri = ptr->mimeUri();
561  if ( uri.isValid() )
562  lst.append( uri );
563  }
564  }
565  return QgsMimeDataUtils::encodeUriList( lst );
566 }
567 
568 bool QgsBrowserModel::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent )
569 {
570  Q_UNUSED( row );
571  Q_UNUSED( column );
572 
573  QgsDataItem *destItem = dataItem( parent );
574  if ( !destItem )
575  {
576  QgsDebugMsgLevel( QStringLiteral( "DROP PROBLEM!" ), 4 );
577  return false;
578  }
579 
580  return destItem->handleDrop( data, action );
581 }
582 
583 QgsDataItem *QgsBrowserModel::dataItem( const QModelIndex &idx ) const
584 {
585  void *v = idx.internalPointer();
586  QgsDataItem *d = reinterpret_cast<QgsDataItem *>( v );
587  Q_ASSERT( !v || d );
588  return d;
589 }
590 
591 bool QgsBrowserModel::canFetchMore( const QModelIndex &parent ) const
592 {
593  QgsDataItem *item = dataItem( parent );
594  // if ( item )
595  // QgsDebugMsg( QStringLiteral( "path = %1 canFetchMore = %2" ).arg( item->path() ).arg( item && ! item->isPopulated() ) );
596  return ( item && item->state() == QgsDataItem::NotPopulated );
597 }
598 
599 void QgsBrowserModel::fetchMore( const QModelIndex &parent )
600 {
601  QgsDataItem *item = dataItem( parent );
602 
603  if ( !item || item->state() == QgsDataItem::Populating || item->state() == QgsDataItem::Populated )
604  return;
605 
606  QgsDebugMsgLevel( "path = " + item->path(), 4 );
607 
608  item->populate();
609 }
610 
611 /* Refresh dir path */
612 void QgsBrowserModel::refresh( const QString &path )
613 {
614  QModelIndex index = findPath( path );
615  refresh( index );
616 }
617 
618 /* Refresh item */
619 void QgsBrowserModel::refresh( const QModelIndex &index )
620 {
621  QgsDataItem *item = dataItem( index );
622  if ( !item || item->state() == QgsDataItem::Populating )
623  return;
624 
625  QgsDebugMsgLevel( "Refresh " + item->path(), 4 );
626 
627  item->refresh();
628 }
629 
630 void QgsBrowserModel::addFavoriteDirectory( const QString &directory, const QString &name )
631 {
632  Q_ASSERT( mFavorites );
633  mFavorites->addDirectory( directory, name );
634 }
635 
636 void QgsBrowserModel::removeFavorite( const QModelIndex &index )
637 {
638  QgsDirectoryItem *item = dynamic_cast<QgsDirectoryItem *>( dataItem( index ) );
639  if ( !item )
640  return;
641 
642  mFavorites->removeDirectory( item );
643 }
644 
646 {
647  QgsSettings settings;
648  QStringList hiddenItems = settings.value( QStringLiteral( "browser/hiddenPaths" ),
649  QStringList() ).toStringList();
650  int idx = hiddenItems.indexOf( item->path() );
651  if ( idx != -1 )
652  {
653  hiddenItems.removeAt( idx );
654  }
655  else
656  {
657  hiddenItems << item->path();
658  }
659  settings.setValue( QStringLiteral( "browser/hiddenPaths" ), hiddenItems );
660  if ( item->parent() )
661  {
662  item->parent()->deleteChildItem( item );
663  }
664  else
665  {
666  removeRootItem( item );
667  }
668 }
669 
670 
671 void QgsBrowserModel::removeRootItem( QgsDataItem *item )
672 {
673  int i = mRootItems.indexOf( item );
674  beginRemoveRows( QModelIndex(), i, i );
675  mRootItems.remove( i );
676  if ( !mDriveItems.key( item ).isEmpty() )
677  {
678  mDriveItems.remove( mDriveItems.key( item ) );
679  }
680  item->deleteLater();
681  endRemoveRows();
682 }
683 
A Collection: logical collection of layers or subcollections, e.g.
Definition: qgsdataitem.h:540
virtual void refresh(const QVector< QgsDataItem * > &children)
Refresh the items from a specified list of child items.
void beginInsertItems(QgsDataItem *parent, int first, int last)
void setSortKey(const QVariant &key)
Sets a custom sorting key for the item.
bool canFetchMore(const QModelIndex &parent) const override
void connectionsChanged()
Connections changed in the browser, forwarded to the widget and used to notify the provider dialogs o...
void dataChanged(QgsDataItem *item)
static void deleteLater(QVector< QgsDataItem * > &items)
QString name() const
Returns the name of the item (the displayed text for the item).
Definition: qgsdataitem.h:283
void hidePath(QgsDataItem *item)
Hide the given path in the browser model.
QgsBrowserModel(QObject *parent=nullptr)
Constructor for QgsBrowserModel, with the specified parent object.
virtual Capabilities capabilities2() const
Returns the capabilities for the data item.
Definition: qgsdataitem.h:248
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
QgsDataItem * parent() const
Gets item parent.
Definition: qgsdataitem.h:269
virtual QgsDataItem * createDataItem(const QString &path, QgsDataItem *parentItem)=0
Create a new instance of QgsDataItem (or null) for given path and parent item.
void connectionsChanged()
Emitted when the provider&#39;s connections of the child items have changed This signal is normally forwa...
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void fetchMore(const QModelIndex &parent) override
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
void refreshDrives()
Refreshes the list of drive items, removing any corresponding to removed drives and adding newly adde...
virtual bool handleDrop(const QMimeData *, Qt::DropAction)
Attempts to process the mime data dropped on this item.
Definition: qgsdataitem.h:180
QModelIndex findPath(const QString &path, Qt::MatchFlag matchFlag=Qt::MatchExactly)
Returns index of item with given path.
void beginRemoveItems(QgsDataItem *parent, int first, int last)
virtual QIcon icon()
Q_DECL_DEPRECATED void connectItem(QgsDataItem *item)
State state() const
#define PROJECT_HOME_PREFIX
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
static QMimeData * encodeUriList(const UriList &layers)
Encodes a URI list to a new QMimeData object.
virtual bool rename(const QString &name)
Sets a new name for the item, and returns true if the item was successfully renamed.
void itemStateChanged(QgsDataItem *item, QgsDataItem::State oldState)
QStringList mimeTypes() const override
void projectSaved()
Emitted when the project file has been written and closed.
QVector< QgsDataItem * > children() const
Definition: qgsdataitem.h:275
bool isValid() const
Returns whether the object contains valid data.
bool hasChildren(const QModelIndex &parent=QModelIndex()) const override
void endRemoveItems()
Item path used to access path in the tree, see QgsDataItem::mPath.
virtual QgsMimeDataUtils::Uri mimeUri() const
Returns mime URI for the data item.
Definition: qgsdataitem.h:205
QString homePath
Definition: qgsproject.h:94
QgsDirectoryItem * mProjectHome
QgsFavoritesItem * mFavorites
void beginRemoveItems(QgsDataItem *parent, int first, int last)
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QModelIndex parent(const QModelIndex &index) const override
QVector< QgsDataItem * > mRootItems
QgsDataItem * dataItem(const QModelIndex &idx) const
Returns the data item at the specified index, or a nullptr if no item exists at the index...
void readProject(const QDomDocument &)
Emitted when a project is being read.
virtual bool hasDragEnabled() const
Returns true if the item may be dragged.
Definition: qgsdataitem.h:197
#define HOME_PREFIX
Children not yet created.
Definition: qgsdataitem.h:104
Creating children in separate thread (populating or refreshing)
Definition: qgsdataitem.h:105
QString path() const
Definition: qgsdataitem.h:292
void initialize()
Delayed initialization, needed because the provider registry must be already populated.
void removeFavorite(const QModelIndex &index)
Removes a favorite directory from its corresponding model index.
Type type() const
Definition: qgsdataitem.h:264
virtual int capabilities()=0
Returns combination of flags from QgsDataProvider::DataCapabilities.
QgsBrowserWatcher(QgsDataItem *item)
bool hasChildren()
static bool hiddenPath(const QString &path)
Check if the given path is hidden from the browser model.
void reload()
Reload the whole model.
A directory: contains subdirectories and layers.
Definition: qgsdataitem.h:571
Base class for all items in the model.
Definition: qgsdataitem.h:49
virtual QVariant sortKey() const
Returns the sorting key for the item.
Custom sort role, see QgsDataItem::sortKey()
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
~QgsBrowserModel() override
void addFavoriteDirectory(const QString &directory, const QString &name=QString())
Adds a directory to the favorites group.
virtual void populate(const QVector< QgsDataItem * > &children)
void beginInsertItems(QgsDataItem *parent, int first, int last)
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Contains various Favorites directories.
Definition: qgsdataitem.h:687
void removeDirectory(QgsDirectoryItem *item)
Removes an existing directory from the favorites group.
Item can be renamed.
Definition: qgsdataitem.h:214
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
void addDirectory(const QString &directory, const QString &name=QString())
Adds a new directory to the favorites group.
virtual QString comments() const
Returns comments of the layer.
Definition: qgsdataitem.h:494
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:411
int columnCount(const QModelIndex &parent=QModelIndex()) const override
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
void stateChanged(const QModelIndex &index, QgsDataItem::State oldState)
Emitted when item children fetch was finished.
void refresh(const QString &path)
Refresh item specified by path.
QList< QgsMimeDataUtils::Uri > UriList
void endInsertItems()
QMimeData * mimeData(const QModelIndexList &indexes) const override
void homePathChanged()
Emitted when the home path of the project changes.
Item that represents a layer that can be opened with one of the providers.
Definition: qgsdataitem.h:435
virtual void deleteChildItem(QgsDataItem *child)
Removes and deletes a child item, emitting relevant signals to the model.
virtual QString name()=0
Human-readable name of the provider name.
void itemDataChanged(QgsDataItem *item)
QString toolTip() const
Definition: qgsdataitem.h:324
Qt::ItemFlags flags(const QModelIndex &index) const override
Children created.
Definition: qgsdataitem.h:106
virtual bool acceptDrop()
Returns whether the item accepts drag and dropped layers - e.g.
Definition: qgsdataitem.h:173
QModelIndex findItem(QgsDataItem *item, QgsDataItem *parent=nullptr) const
Returns the model index corresponding to the specified data item.
void addRootItems()
Populates the model.
static QgsDataItemProviderRegistry * dataItemProviderRegistry()
Returns the application&#39;s data item provider registry, which keeps a list of data item providers that...
This is the interface for those who want to add custom data items to the browser tree.
void stateChanged(QgsDataItem *item, QgsDataItem::State oldState)