1 /***************************************************************************
2 qgsdataitem.h - Items representing data
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 #ifndef QGSDATAITEM_H
18 #define QGSDATAITEM_H
19
20 #include "qgis_sip.h"
21 #include "qgis_core.h"
22 #include <QFileSystemWatcher>
23 #include <QFutureWatcher>
24 #include <QIcon>
25 #include <QObject>
26 #include <QPixmap>
27 #include <QString>
28 #include <QTreeWidget>
29 #include <QVector>
30 #include <QDateTime>
31
32 #include "qgsmaplayer.h"
33 #include "qgscoordinatereferencesystem.h"
34 #include "qgsmimedatautils.h"
35 #include "qgswkbtypes.h"
36 #include "qgsabstractdatabaseproviderconnection.h"
37
38 class QgsDataProvider;
39 class QgsDataItem;
40 class QgsAnimatedIcon;
41 class QgsBookmarkManager;
42
43 typedef QgsDataItem *dataItem_t( QString, QgsDataItem * ) SIP_SKIP;
44
45 /**
46 * \ingroup core
47 * \brief Base class for all items in the model.
48 *
49 * Parent/children hierarchy is not based on QObject.
50 */
51 class CORE_EXPORT QgsDataItem : public QObject
52 {
53
54 #ifdef SIP_RUN
55 SIP_CONVERT_TO_SUBCLASS_CODE
56 if ( qobject_cast<QgsLayerItem *>( sipCpp ) )
57 sipType = sipType_QgsLayerItem;
58 else if ( qobject_cast<QgsErrorItem *>( sipCpp ) )
59 sipType = sipType_QgsErrorItem;
60 else if ( qobject_cast<QgsDirectoryItem *>( sipCpp ) )
61 sipType = sipType_QgsDirectoryItem;
62 else if ( qobject_cast<QgsFavoritesItem *>( sipCpp ) )
63 sipType = sipType_QgsFavoritesItem;
64 else if ( qobject_cast<QgsZipItem *>( sipCpp ) )
65 sipType = sipType_QgsZipItem;
66 else if ( qobject_cast<QgsDataCollectionItem *>( sipCpp ) )
67 sipType = sipType_QgsDataCollectionItem;
68 else if ( qobject_cast<QgsProjectItem *>( sipCpp ) )
69 sipType = sipType_QgsProjectItem;
70 else
71 sipType = 0;
72 SIP_END
73 #endif
74
75 Q_OBJECT
76
77 public:
78 enum Type
79 {
80 Collection,
81 Directory,
82 Layer,
83 Error,
84 Favorites, //!< Represents a favorite item
85 Project, //!< Represents a QGIS project
86 Custom, //!< Custom item type
87 Fields, //!< Collection of fields
88 Field, //!< Vector layer field
89 };
90
91 Q_ENUM( Type )
92
93 /**
94 * Constructor for QgsDataItem, with the specified \a parent item.
95 *
96 * The \a name argument specifies the text to show in the model for the item. A translated string should
97 * be used wherever appropriate.
98 *
99 * The \a path argument gives the item path in the browser tree. The \a path string can take any form,
100 * but QgsDataItem items pointing to different logical locations should always use a different item \a path.
101 *
102 * The optional \a providerKey string (added in QGIS 3.12) can be used to specify the key for the QgsDataItemProvider that created this item.
103 */
104 QgsDataItem( QgsDataItem::Type type, QgsDataItem *parent SIP_TRANSFERTHIS, const QString &name, const QString &path, const QString &providerKey = QString() );
105
106 ~QgsDataItem() override;
107
108 bool hasChildren();
109
110 /**
111 * Returns TRUE if the data item is a collection of layers
112 * The default implementation returns FALSE, subclasses must implement this method if their children are layers.
113 * \since QGIS 3.14
114 */
115 virtual bool layerCollection() const;
116
117 int rowCount();
118
119 /**
120 * Create children. Children are not expected to have parent set.
121 * \warning This method MUST BE THREAD SAFE.
122 */
123 virtual QVector<QgsDataItem *> createChildren() SIP_TRANSFERBACK;
124 #ifdef SIP_RUN
125 SIP_VIRTUAL_CATCHER_CODE
126 PyObject *sipResObj = sipCallMethod( 0, sipMethod, "" );
127 // H = Convert a Python object to a mapped type instance.
128 // 5 = 1 (disallows the conversion of Py_None to NULL) + 4 (returns a copy of the C/C++ instance)
129 sipIsErr = !sipResObj || sipParseResult( 0, sipMethod, sipResObj, "H5", sipType_QVector_0101QgsDataItem, &sipRes ) < 0;
130 if ( !sipIsErr )
131 {
132 for ( QgsDataItem *item : sipRes )
133 {
134 PyObject *pyItem = sipGetPyObject( item, sipType_QgsDataItem );
135 if ( pyItem != NULL )
136 {
137 // pyItem is given an extra reference which is removed when the C++ instance’s destructor is called.
138 sipTransferTo( pyItem, Py_None );
139 }
140 }
141 }
142 if ( sipResObj != NULL )
143 {
144 Py_DECREF( sipResObj );
145 }
146 SIP_END
147 #endif
148
149 enum State
150 {
151 NotPopulated, //!< Children not yet created
152 Populating, //!< Creating children in separate thread (populating or refreshing)
153 Populated //!< Children created
154 };
155 Q_ENUM( State )
156
157 //! \since QGIS 2.8
158 State state() const;
159
160 /**
161 * Set item state. It also take care about starting/stopping loading icon animation.
162 * \param state
163 * \since QGIS 2.8
164 */
165 virtual void setState( State state );
166
167 /**
168 * Inserts a new child item. The child will be inserted at a position using an alphabetical order based on mName.
169 * \param child child item to insert. Ownership is transferred, and item parent will be set and relevant connections made.
170 * \param refresh - set to TRUE to refresh populated item, emitting relevant signals to the model
171 * \see deleteChildItem()
172 */
173 virtual void addChildItem( QgsDataItem *child SIP_TRANSFER, bool refresh = false );
174
175 /**
176 * Removes and deletes a child item, emitting relevant signals to the model.
177 * \param child child to remove. Item must exist as a current child.
178 * \see addChildItem()
179 */
180 virtual void deleteChildItem( QgsDataItem *child );
181
182 /**
183 * Removes a child item and returns it without deleting it. Emits relevant signals to model as required.
184 * \param child child to remove
185 * \returns pointer to the removed item or NULLPTR if no such item was found
186 */
187 virtual QgsDataItem *removeChildItem( QgsDataItem *child ) SIP_TRANSFERBACK;
188
189 /**
190 * Returns TRUE if this item is equal to another item (by testing item type and path).
191 */
192 virtual bool equal( const QgsDataItem *other );
193
194 /**
195 * Returns source widget from data item for QgsBrowserPropertiesWidget
196 *
197 * Use QgsDataItemGuiProvider::createParamWidget() instead
198 *
199 * \deprecated QGIS 3.10
200 */
paramWidget()201 Q_DECL_DEPRECATED virtual QWidget *paramWidget() SIP_FACTORY SIP_DEPRECATED { return nullptr; }
202
203 /**
204 * Returns the list of actions available for this item. This is usually used for the popup menu on right-clicking
205 * the item. Subclasses should override this to provide actions.
206 *
207 * Subclasses should ensure that ownership of created actions is correctly handled by parenting them
208 * to the specified parent widget.
209 */
210 virtual QList<QAction *> actions( QWidget *parent );
211
212 /**
213 * Returns the list of menus available for this item. This is usually used for the popup menu on right-clicking
214 * the item. Subclasses should override this to provide actions. Subclasses should ensure that ownership of
215 * created menus is correctly handled by parenting them to the specified parent widget.
216 * \param parent a parent widget of the menu
217 * \returns list of menus
218 * \since QGIS 3.0
219 */
220 virtual QList<QMenu *> menus( QWidget *parent );
221
222 /**
223 * Returns whether the item accepts drag and dropped layers - e.g. for importing a dataset to a provider.
224 * Subclasses should override this and handleDrop() to accept dropped layers.
225 * \see handleDrop()
226 * \see QgsDataItemGuiProvider::handleDrop()
227 *
228 * \deprecated QGIS 3.10
229 */
acceptDrop()230 Q_DECL_DEPRECATED virtual bool acceptDrop() SIP_DEPRECATED { return false; }
231
232 /**
233 * Attempts to process the mime data dropped on this item. Subclasses must override this and acceptDrop() if they
234 * accept dropped layers.
235 * \see acceptDrop()
236 * \see QgsDataItemGuiProvider::handleDrop()
237 *
238 * \deprecated QGIS 3.10
239 */
handleDrop(const QMimeData *,Qt::DropAction)240 Q_DECL_DEPRECATED virtual bool handleDrop( const QMimeData * /*data*/, Qt::DropAction /*action*/ ) SIP_DEPRECATED { return false; }
241
242 /**
243 * Called when a user double clicks on the item. Subclasses should return TRUE
244 * if they have implemented a double-click handler and do not want the default
245 * double-click behavior for items.
246 * \since QGIS 3.0
247 */
248 virtual bool handleDoubleClick();
249
250 /**
251 * Returns TRUE if the item may be dragged.
252 * Default implementation returns FALSE.
253 * A draggable item has to implement mimeUri() that will be used to pass data.
254 * \see mimeUri()
255 * \since QGIS 3.0
256 */
hasDragEnabled()257 virtual bool hasDragEnabled() const { return false; }
258
259 /**
260 * Returns mime URI for the data item.
261 * Items that return valid URI will be returned in mime data when dragging a selection from browser model.
262 * \see hasDragEnabled()
263 * \since QGIS 3.0
264 */
mimeUri()265 virtual QgsMimeDataUtils::Uri mimeUri() const { return QgsMimeDataUtils::Uri(); }
266
267 enum Capability
268 {
269 NoCapabilities = 0,
270 SetCrs = 1 << 0, //!< Can set CRS on layer or group of layers. \deprecated since QGIS 3.6 -- no longer used by QGIS and will be removed in QGIS 4.0
271 Fertile = 1 << 1, //!< Can create children. Even items without this capability may have children, but cannot create them, it means that children are created by item ancestors.
272 Fast = 1 << 2, //!< CreateChildren() is fast enough to be run in main thread when refreshing items, most root items (wms,wfs,wcs,postgres...) are considered fast because they are reading data only from QgsSettings
273 Collapse = 1 << 3, //!< The collapse/expand status for this items children should be ignored in order to avoid undesired network connections (wms etc.)
274 Rename = 1 << 4, //!< Item can be renamed
275 Delete = 1 << 5, //!< Item can be deleted
276 };
Q_DECLARE_FLAGS(Capabilities,Capability)277 Q_DECLARE_FLAGS( Capabilities, Capability )
278
279 /**
280 * Writes the selected crs into data source. The original data source will be modified when calling this
281 * method.
282 *
283 * \deprecated since QGIS 3.6. This method is no longer used by QGIS and will be removed in QGIS 4.0.
284 */
285 Q_DECL_DEPRECATED virtual bool setCrs( const QgsCoordinateReferenceSystem &crs ) SIP_DEPRECATED
286 {
287 Q_UNUSED( crs )
288 return false;
289 }
290
291 /**
292 * Sets a new \a name for the item, and returns TRUE if the item was successfully renamed.
293 *
294 * Items which implement this method should return the QgsDataItem::Rename capability.
295 *
296 * The default implementation does nothing.
297 *
298 * Use QgsDataItemGuiProvider:
299 *
300 * \since QGIS 3.4
301 * \deprecated QGIS 3.10
302 */
303 Q_DECL_DEPRECATED virtual bool rename( const QString &name ) SIP_DEPRECATED;
304
305 // ### QGIS 4 - rename to capabilities()
306
307 /**
308 * Returns the capabilities for the data item.
309 *
310 * \see setCapabilities()
311 */
capabilities2()312 virtual Capabilities capabilities2() const { return mCapabilities; }
313
314 /**
315 * Sets the capabilities for the data item.
316 *
317 * \see capabilities2()
318 */
setCapabilities(Capabilities capabilities)319 virtual void setCapabilities( Capabilities capabilities ) { mCapabilities = capabilities; }
320
321 // static methods
322
323 // Find child index in vector of items using '==' operator
324 static int findItem( QVector<QgsDataItem *> items, QgsDataItem *item );
325
326 // members
327
type()328 Type type() const { return mType; }
329
330 /**
331 * Gets item parent. QgsDataItem maintains its own items hierarchy, it does not use
332 * QObject hierarchy.
333 */
parent()334 QgsDataItem *parent() const { return mParent; }
335
336 /**
337 * Set item parent and connect / disconnect parent to / from item signals.
338 * It does not add itself to parents children (mChildren)
339 */
340 void setParent( QgsDataItem *parent );
children()341 QVector<QgsDataItem *> children() const { return mChildren; }
342 virtual QIcon icon();
343
344 /**
345 * Returns the name of the item (the displayed text for the item).
346 *
347 * \see setName()
348 */
name()349 QString name() const { return mName; }
350
351 /**
352 * Sets the \a name of the item (the displayed text for the item).
353 *
354 * \see name()
355 */
356 void setName( const QString &name );
357
path()358 QString path() const { return mPath; }
setPath(const QString & path)359 void setPath( const QString &path ) { mPath = path; }
360
361 /**
362 * Returns the provider key that created this item (e.g. "PostGIS")
363 *
364 * If key has a prefix "special:", it marks that the item was not created with a provider,
365 * but manually. For example "special:Favorites", "special:Home"
366 *
367 * \since QGIS 3.12
368 */
369 QString providerKey() const;
370
371 /**
372 * Sets the provider key that created this item (e.g. "PostGIS")
373 *
374 * If key has a prefix "special:", it marks that the item was not created with a provider,
375 * but manually. For example "special:Favorites"
376 *
377 * \since QGIS 3.12
378 */
379 void setProviderKey( const QString &value );
380
381 //! Create path component replacing path separators
382 static QString pathComponent( const QString &component );
383
384 /**
385 * Returns the sorting key for the item. By default name() is returned,
386 * but setSortKey() can be used to set a custom sort key for the item.
387 *
388 * Alternatively subclasses can override this method to return a custom
389 * sort key.
390 *
391 * \see setSortKey()
392 * \since QGIS 3.0
393 */
394 virtual QVariant sortKey() const;
395
396 /**
397 * Sets a custom sorting \a key for the item.
398 * \see sortKey()
399 * \since QGIS 3.0
400 */
401 void setSortKey( const QVariant &key );
402
403
404 // Because QIcon (QPixmap) must not be used in outside the GUI thread, it is
405 // not possible to set mIcon in constructor. Either use mIconName/setIconName()
406 // or implement icon().
setIcon(const QIcon & icon)407 void setIcon( const QIcon &icon ) { mIcon = icon; }
setIconName(const QString & iconName)408 void setIconName( const QString &iconName ) { mIconName = iconName; }
409
setToolTip(const QString & msg)410 void setToolTip( const QString &msg ) { mToolTip = msg; }
toolTip()411 QString toolTip() const { return mToolTip; }
412
413 // deleteLater() items and clear the vector
414 static void deleteLater( QVector<QgsDataItem *> &items );
415
416 //! Move object and all its descendants to thread
417 void moveToThread( QThread *targetThread );
418
419 /**
420 * For data items that represent a DB connection or one of its children,
421 * this method returns a connection.
422 * All other data items will return NULL.
423 *
424 * Ownership of the returned objects is transferred to the caller.
425 *
426 * \since QGIS 3.16
427 */
428 virtual QgsAbstractDatabaseProviderConnection *databaseConnection() const SIP_FACTORY;
429
430 protected:
431 virtual void populate( const QVector<QgsDataItem *> &children );
432
433 /**
434 * Refresh the items from a specified list of child items.
435 */
436 virtual void refresh( const QVector<QgsDataItem *> &children );
437
438 /**
439 * The item is scheduled to be deleted. E.g. if deleteLater() is called when
440 * item is in Populating state (createChildren() running in another thread),
441 * the deferredDelete() returns TRUE and item will be deleted once Populating finished.
442 * Items with slow reateChildren() (for example network or database based) may
443 * check during createChildren() if deferredDelete() returns TRUE and return from
444 * createChildren() immediately because result will be useless.
445 */
deferredDelete()446 bool deferredDelete() { return mDeferredDelete; }
447
448 Type mType;
449 Capabilities mCapabilities;
450 QgsDataItem *mParent = nullptr;
451 QVector<QgsDataItem *> mChildren; // easier to have it always
452 State mState;
453 QString mName;
454 QString mProviderKey;
455 // Path is slash ('/') separated chain of item identifiers which are usually item names, but may be different if it is
456 // necessary to distinguish paths of two providers to the same source (e.g GRASS location and standard directory have the same
457 // name but different paths). Identifiers in path must not contain '/' characters.
458 // The path is used to identify item in tree.
459 QString mPath;
460 QString mToolTip;
461 QString mIconName;
462 QIcon mIcon;
463 QMap<QString, QIcon> mIconMap;
464
465 //! Custom sort key. If invalid, name() will be used for sorting instead.
466 QVariant mSortKey;
467
468 public slots:
469
470 /**
471 * Safely delete the item:
472 *
473 * - disconnects parent
474 * - unsets parent (but does not remove itself)
475 * - deletes all its descendants recursively
476 * - waits until Populating state (createChildren() in thread) finished without blocking main thread
477 * - calls QObject::deleteLater()
478 */
479 virtual void deleteLater();
480
481 // Populate children using children vector created by createChildren()
482 // \param foreground run createChildren in foreground
483 virtual void populate( bool foreground = false );
484
485 //! Remove children recursively and set as not populated. This is used when refreshing collapsed items.
486 virtual void depopulate();
487
488 virtual void refresh();
489
490 /**
491 * Causes a data item provider to refresh all registered connections.
492 *
493 * If \a providerKey is specified then only the matching provider will be refreshed. Otherwise,
494 * all providers will be refreshed (which is potentially very expensive!).
495 */
496 virtual void refreshConnections( const QString &providerKey = QString() );
497
498 virtual void childrenCreated();
499
500 signals:
501 void beginInsertItems( QgsDataItem *parent, int first, int last );
502 void endInsertItems();
503 void beginRemoveItems( QgsDataItem *parent, int first, int last );
504 void endRemoveItems();
505 void dataChanged( QgsDataItem *item );
506 void stateChanged( QgsDataItem *item, QgsDataItem::State oldState );
507
508 /**
509 * Emitted when the connections of the provider with the specified \a providerKey have changed.
510 *
511 * This signal is normally forwarded to the app in order to refresh the connection
512 * item in the provider dialogs and to refresh the connection items in the other
513 * open browsers.
514 */
515 void connectionsChanged( const QString &providerKey = QString() );
516
517 protected slots:
518
519 /**
520 * Will request a repaint of this icon.
521 *
522 * \since QGIS 3.0
523 */
524 void updateIcon();
525
526 private:
527 static QVector<QgsDataItem *> runCreateChildren( QgsDataItem *item );
528
529 // Set to true if object has to be deleted when possible (nothing running in threads)
530 bool mDeferredDelete;
531 QFutureWatcher< QVector <QgsDataItem *> > *mFutureWatcher;
532 // number of items currently in loading (populating) state
533 static QgsAnimatedIcon *sPopulatingIcon;
534 };
535
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsDataItem::Capabilities)536 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsDataItem::Capabilities )
537
538 /**
539 * \ingroup core
540 * \brief Item that represents a layer that can be opened with one of the providers
541 */
542 class CORE_EXPORT QgsLayerItem : public QgsDataItem
543 {
544 Q_OBJECT
545
546 public:
547 enum LayerType
548 {
549 NoType,
550 Vector,
551 Raster,
552 Point,
553 Line,
554 Polygon,
555 TableLayer,
556 Database,
557 Table,
558 Plugin, //!< Added in 2.10
559 Mesh, //!< Added in 3.2
560 VectorTile //!< Added in 3.14
561 };
562
563 Q_ENUM( LayerType )
564
565 QgsLayerItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &uri, LayerType layerType, const QString &providerKey );
566
567 // --- reimplemented from QgsDataItem ---
568
569 bool equal( const QgsDataItem *other ) override;
570
571 bool hasDragEnabled() const override { return true; }
572
573 QgsMimeDataUtils::Uri mimeUri() const override;
574
575 // --- New virtual methods for layer item derived classes ---
576
577 //! Returns QgsMapLayerType
578 QgsMapLayerType mapLayerType() const;
579
580 /**
581 * Returns the layer item type corresponding to a QgsMapLayer \a layer.
582 * \since QGIS 3.6
583 */
584 static LayerType typeFromMapLayer( QgsMapLayer *layer );
585
586 //! Returns layer uri or empty string if layer cannot be created
587 QString uri() const { return mUri; }
588
589 //! Returns provider key
590 QString providerKey() const { return mProviderKey; }
591
592 /**
593 * Returns the supported CRS
594 * \since QGIS 2.8
595 */
596 QStringList supportedCrs() const { return mSupportedCRS; }
597
598 /**
599 * Returns the supported formats
600 * \since QGIS 2.8
601 */
602 QStringList supportedFormats() const { return mSupportFormats; }
603
604 /**
605 * Returns comments of the layer
606 * \since QGIS 2.12
607 */
608 virtual QString comments() const { return QString(); }
609
610 /**
611 * Returns the string representation of the given \a layerType
612 * \since QGIS 3
613 */
614 static QString layerTypeAsString( LayerType layerType );
615
616 /**
617 * Returns the icon name of the given \a layerType
618 * \since QGIS 3
619 */
620 static QString iconName( LayerType layerType );
621
622 /**
623 * Delete this layer item
624 * Use QgsDataItemGuiProvider::deleteLayer instead
625 *
626 * \deprecated QGIS 3.10
627 */
628 Q_DECL_DEPRECATED virtual bool deleteLayer() SIP_DEPRECATED;
629
630 protected:
631 //! The URI
632 QString mUri;
633 //! The layer type
634 LayerType mLayerType;
635 //! The list of supported CRS
636 QStringList mSupportedCRS;
637 //! The list of supported formats
638 QStringList mSupportFormats;
639
640 public:
641 static QIcon iconPoint();
642 static QIcon iconLine();
643 static QIcon iconPolygon();
644 static QIcon iconTable();
645 static QIcon iconRaster();
646 static QIcon iconDefault();
647 //! Returns icon for mesh layer type
648 static QIcon iconMesh();
649 //! Returns icon for vector tile layer
650 static QIcon iconVectorTile();
651
652 //! \returns the layer name
653 virtual QString layerName() const { return name(); }
654
655 };
656
657
658 /**
659 * \ingroup core
660 * \brief A Collection: logical collection of layers or subcollections, e.g. GRASS location/mapset, database? wms source?
661 */
662 class CORE_EXPORT QgsDataCollectionItem : public QgsDataItem
663 {
664 Q_OBJECT
665 public:
666
667 /**
668 * Constructor for QgsDataCollectionItem, with the specified \a parent item.
669 *
670 * The \a name argument specifies the text to show in the model for the item. A translated string should
671 * be used wherever appropriate.
672 *
673 * The \a path argument gives the item path in the browser tree. The \a path string can take any form,
674 * but QgsDataCollectionItem items pointing to different logical locations should always use a different item \a path.
675 *
676 * The optional \a providerKey string can be used to specify the key for the QgsDataItemProvider that created this item.
677 */
678 QgsDataCollectionItem( QgsDataItem *parent SIP_TRANSFERTHIS, const QString &name, const QString &path = QString(), const QString &providerKey = QString() );
679
680 ~QgsDataCollectionItem() override;
681
addChild(QgsDataItem * item SIP_TRANSFER)682 void addChild( QgsDataItem *item SIP_TRANSFER ) { mChildren.append( item ); }
683
684 /**
685 * Returns the standard browser directory icon.
686 * \see iconDataCollection()
687 */
688 static QIcon iconDir();
689
690 /**
691 * Returns the standard browser data collection icon.
692 * \see iconDir()
693 */
694 static QIcon iconDataCollection();
695
696 QgsAbstractDatabaseProviderConnection *databaseConnection() const override;
697
698 protected:
699
700 /**
701 * Shared open directory icon.
702 * \since QGIS 3.4
703 */
704 static QIcon openDirIcon();
705
706 /**
707 * Shared home directory icon.
708 * \since QGIS 3.4
709 */
710 static QIcon homeDirIcon();
711
712 };
713
714
715 /**
716 * \ingroup core
717 * \brief A Collection that represents a database schema item
718 * \since QGIS 3.16
719 */
720 class CORE_EXPORT QgsDatabaseSchemaItem : public QgsDataCollectionItem
721 {
722 Q_OBJECT
723 public:
724
725 /**
726 * Constructor for QgsDatabaseSchemaItem, with the specified \a parent item.
727 *
728 * The \a name argument specifies the text to show in the model for the item. A translated string should
729 * be used wherever appropriate.
730 *
731 * The \a path argument gives the item path in the browser tree. The \a path string can take any form,
732 * but QgsSchemaItem items pointing to different logical locations should always use a different item \a path.
733 *
734 * The optional \a providerKey string can be used to specify the key for the QgsDataItemProvider that created this item.
735 */
736 QgsDatabaseSchemaItem( QgsDataItem *parent SIP_TRANSFERTHIS, const QString &name, const QString &path = QString(), const QString &providerKey = QString() );
737
738 ~QgsDatabaseSchemaItem() override;
739
740 QgsAbstractDatabaseProviderConnection *databaseConnection() const override;
741
742 /**
743 * Returns the standard browser data collection icon.
744 * \see iconDir()
745 */
746 static QIcon iconDataCollection();
747
748 };
749
750
751
752 /**
753 * \ingroup core
754 * \brief A Collection that represents a root group of connections from a single data provider
755 * \since QGIS 3.16
756 */
757 class CORE_EXPORT QgsConnectionsRootItem : public QgsDataCollectionItem
758 {
759 Q_OBJECT
760 public:
761
762 /**
763 * Constructor for QgsConnectionsRootItem, with the specified \a parent item.
764 *
765 * The \a name argument specifies the text to show in the model for the item. A translated string should
766 * be used wherever appropriate.
767 *
768 * The \a path argument gives the item path in the browser tree. The \a path string can take any form,
769 * but QgsSchemaItem items pointing to different logical locations should always use a different item \a path.
770 *
771 * The optional \a providerKey string can be used to specify the key for the QgsDataItemProvider that created this item.
772 */
773 QgsConnectionsRootItem( QgsDataItem *parent SIP_TRANSFERTHIS, const QString &name, const QString &path = QString(), const QString &providerKey = QString() );
774
775 ~QgsConnectionsRootItem() override = default;
776 };
777
778
779 /**
780 * \ingroup core
781 * \brief A directory: contains subdirectories and layers
782 */
783 class CORE_EXPORT QgsDirectoryItem : public QgsDataCollectionItem
784 {
785 Q_OBJECT
786 public:
787
788 /**
789 * Constructor for QgsDirectoryItem, with the specified \a parent item.
790 *
791 * The \a name argument specifies the text to show in the model for the item. This is usually
792 * the directory name, but in certain cases may differ for special directories (e.g. "Home").
793 * If a non-directory-name text is used, it should be a translated string when appropriate.
794 *
795 * The \a path argument specifies the directory path in the file system (e.g. "/home/gsherman/stuff"). A valid
796 * directory path must be specified.
797 */
798 QgsDirectoryItem( QgsDataItem *parent SIP_TRANSFERTHIS, const QString &name, const QString &path );
799
800
801 // TODO QGIS 4.0 -- rename "name" to "title" or "text" or something more descriptive, and "path" to something
802 // else to clarify the role of dirPath vs path
803
804 /**
805 * Constructor for QgsDirectoryItem, with the specified \a parent item.
806 *
807 * The \a name argument specifies the text to show in the model for the item. This is usually
808 * the directory name, but in certain cases may differ for special directories (e.g. "Home").
809 * If a non-directory-name text is used, it should be a translated string when appropriate.
810 *
811 * The \a dirPath argument specifies the directory path in the file system (e.g. "/home/gsherman/stuff"). A valid
812 * directory path must be specified.
813 *
814 * The \a path argument gives the item path in the browser tree. The \a path string can take any form, but is usually
815 * the same as \a dirPath or \a dirPath with a prefix, e.g. "favorites:/home/gsherman/Downloads"). QgsDirectoryItem
816 * items pointing to different \a dirPaths should always use a different item \a path.
817 *
818 * The optional \a providerKey string can be used to specify the key for the QgsDataItemProvider that created this item.
819 */
820 QgsDirectoryItem( QgsDataItem *parent SIP_TRANSFERTHIS, const QString &name, const QString &dirPath, const QString &path, const QString &providerKey = QString() );
821
822 void setState( State state ) override;
823
824 QVector<QgsDataItem *> createChildren() override;
825
826 /**
827 * Returns the full path to the directory the item represents.
828 */
dirPath()829 QString dirPath() const { return mDirPath; }
830
831 bool equal( const QgsDataItem *other ) override;
832 QIcon icon() override;
833 Q_DECL_DEPRECATED QWidget *paramWidget() override SIP_FACTORY SIP_DEPRECATED;
hasDragEnabled()834 bool hasDragEnabled() const override { return true; }
835 QgsMimeDataUtils::Uri mimeUri() const override;
836
837 //! Check if the given path is hidden from the browser model
838 static bool hiddenPath( const QString &path );
839
840 public slots:
841 void childrenCreated() override;
842 void directoryChanged();
843
844 protected:
845 void init();
846 QString mDirPath;
847
848 private:
849 QFileSystemWatcher *mFileSystemWatcher = nullptr;
850 bool mRefreshLater;
851 QDateTime mLastScan;
852 };
853
854 /**
855 * \ingroup core
856 * \brief Data item that can be used to represent QGIS projects.
857 */
858 class CORE_EXPORT QgsProjectItem : public QgsDataItem
859 {
860 Q_OBJECT
861 public:
862
863 /**
864 * \brief A data item holding a reference to a QGIS project file.
865 * \param parent The parent data item.
866 * \param name The name of the of the project. Displayed to the user.
867 * \param path The full path to the project.
868 * \param providerKey key of the provider that created this item
869 */
870 QgsProjectItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &providerKey = QString() );
871
hasDragEnabled()872 bool hasDragEnabled() const override { return true; }
873
874 QgsMimeDataUtils::Uri mimeUri() const override;
875
876 };
877
878 /**
879 * \ingroup core
880 * \brief Data item that can be used to report problems (e.g. network error)
881 */
882 class CORE_EXPORT QgsErrorItem : public QgsDataItem
883 {
884 Q_OBJECT
885 public:
886
887 QgsErrorItem( QgsDataItem *parent, const QString &error, const QString &path );
888
889 };
890
891 // ---------
892
893 // TODO: move to qgis_gui for QGIS 4
894
895 /**
896 * \ingroup core
897 * \class QgsDirectoryParamWidget
898 *
899 * \brief Browser parameter widget implementation for directory items.
900 */
901 class CORE_EXPORT QgsDirectoryParamWidget : public QTreeWidget
902 {
903 Q_OBJECT
904
905 public:
906 QgsDirectoryParamWidget( const QString &path, QWidget *parent SIP_TRANSFERTHIS = nullptr );
907
908 protected:
909 void mousePressEvent( QMouseEvent *event ) override;
910
911 public slots:
912 void showHideColumn();
913 };
914
915 /**
916 * \ingroup core
917 * \brief Contains various Favorites directories
918 * \since QGIS 3.0
919 */
920 class CORE_EXPORT QgsFavoritesItem : public QgsDataCollectionItem
921 {
922 Q_OBJECT
923 public:
924
925 /**
926 * Constructor for QgsFavoritesItem. Accepts a path argument specifying the file path associated with
927 * the item.
928 */
929 QgsFavoritesItem( QgsDataItem *parent, const QString &name, const QString &path = QString() );
930
931 QVector<QgsDataItem *> createChildren() override;
932
933 /**
934 * Adds a new \a directory to the favorites group.
935 *
936 * If \a name is specified, it will be used as the favorite's name. Otherwise
937 * the name will be set to match \a directory.
938 *
939 * \see removeDirectory()
940 */
941 void addDirectory( const QString &directory, const QString &name = QString() );
942
943 /**
944 * Removes an existing directory from the favorites group.
945 * \see addDirectory()
946 */
947 void removeDirectory( QgsDirectoryItem *item );
948
949 /**
950 * Renames the stored favorite with corresponding \a path a new \a name.
951 */
952 void renameFavorite( const QString &path, const QString &name );
953
954 //! Icon for favorites group
955 static QIcon iconFavorites();
956
957 QVariant sortKey() const override;
958
959 private:
960 QVector<QgsDataItem *> createChildren( const QString &favDir, const QString &name );
961 };
962
963 /**
964 * \ingroup core
965 * \brief A zip file: contains layers, using GDAL/OGR VSIFILE mechanism
966 */
967 class CORE_EXPORT QgsZipItem : public QgsDataCollectionItem
968 {
969 Q_OBJECT
970
971 protected:
972 QString mFilePath;
973 QString mVsiPrefix;
974 QStringList mZipFileList;
975
976 public:
977 //! Constructor
978 QgsZipItem( QgsDataItem *parent, const QString &name, const QString &path );
979
980 //! Constructor
981 QgsZipItem( QgsDataItem *parent, const QString &name, const QString &filePath, const QString &path, const QString &providerKey = QString() );
982
983 QVector<QgsDataItem *> createChildren() override;
984 QStringList getZipFileList();
985
986 //! \note not available via Python bindings
987 static QVector<dataItem_t *> sDataItemPtr SIP_SKIP;
988 static QStringList sProviderNames;
989
vsiPrefix(const QString & uri)990 static QString vsiPrefix( const QString &uri ) { return qgsVsiPrefix( uri ); }
991
992 /**
993 * Creates a new data item from the specified path.
994 */
995 static QgsDataItem *itemFromPath( QgsDataItem *parent, const QString &path, const QString &name ) SIP_FACTORY;
996
997 /**
998 * Creates a new data item from the specified path.
999 * \note available in Python as itemFromFilePath
1000 */
1001 static QgsDataItem *itemFromPath( QgsDataItem *parent, const QString &filePath, const QString &name, const QString &path ) SIP_FACTORY SIP_PYNAME( itemFromFilePath );
1002
1003 static QIcon iconZip();
1004
1005 private:
1006 void init();
1007 };
1008
1009
1010 /**
1011 * \ingroup core
1012 * \brief A collection of field items with some internal logic to retrieve
1013 * the fields and a the vector layer instance from a connection URI,
1014 * the schema and the table name.
1015 * \since QGIS 3.16
1016 */
1017 class CORE_EXPORT QgsFieldsItem : public QgsDataItem
1018 {
1019 Q_OBJECT
1020
1021 public:
1022
1023 /**
1024 * Constructor for QgsFieldsItem, with the specified \a parent item.
1025 *
1026 * The \a path argument gives the item path in the browser tree. The \a path string can take any form,
1027 * but QgsDataItem items pointing to different logical locations should always use a different item \a path.
1028 * The \connectionUri argument is the connection part of the layer URI that it is used internally to create
1029 * a connection and retrieve fields information.
1030 * The \a providerKey string can be used to specify the key for the QgsDataItemProvider that created this item.
1031 * The \a schema and \a tableName are used to retrieve the layer and field information from the \a connectionUri.
1032 */
1033 QgsFieldsItem( QgsDataItem *parent SIP_TRANSFERTHIS,
1034 const QString &path,
1035 const QString &connectionUri,
1036 const QString &providerKey,
1037 const QString &schema,
1038 const QString &tableName );
1039
1040 ~QgsFieldsItem() override;
1041
1042 QVector<QgsDataItem *> createChildren() override;
1043
1044 QIcon icon() override;
1045
1046 /**
1047 * Returns the schema name
1048 */
1049 QString schema() const;
1050
1051 /**
1052 * Returns the table name
1053 */
1054 QString tableName() const;
1055
1056 /**
1057 * Returns the connection URI
1058 */
1059 QString connectionUri() const;
1060
1061 /**
1062 * Creates and returns a (possibly NULL) layer from the connection URI and schema/table information
1063 */
1064 QgsVectorLayer *layer() SIP_FACTORY;
1065
1066 /**
1067 * Returns the (possibly NULL) properties of the table this fields belong to.
1068 * \since QGIS 3.16
1069 */
1070 QgsAbstractDatabaseProviderConnection::TableProperty *tableProperty() const;
1071
1072 private:
1073
1074 QString mSchema;
1075 QString mTableName;
1076 QString mConnectionUri;
1077 std::unique_ptr<QgsAbstractDatabaseProviderConnection::TableProperty> mTableProperty;
1078
1079 };
1080
1081
1082 /**
1083 * \ingroup core
1084 * \brief A layer field item, information about the connection URI, the schema and the
1085 * table as well as the layer instance the field belongs to can be retrieved
1086 * from the parent QgsFieldsItem object.
1087 * \since QGIS 3.16
1088 */
1089 class CORE_EXPORT QgsFieldItem : public QgsDataItem
1090 {
1091 Q_OBJECT
1092 public:
1093
1094 /**
1095 * Constructor for QgsFieldItem, with the specified \a parent item and \a field.
1096 * \note parent item must be a QgsFieldsItem
1097 */
1098 QgsFieldItem( QgsDataItem *parent SIP_TRANSFERTHIS,
1099 const QgsField &field );
1100
1101 ~QgsFieldItem() override;
1102
1103 QIcon icon() override;
1104
1105 //QgsField field() const;
1106
1107
1108 private:
1109
1110 const QgsField mField;
1111
1112 };
1113
1114
1115
1116 ///@cond PRIVATE
1117 #ifndef SIP_RUN
1118
1119 /**
1120 * \ingroup core
1121 * \brief A directory item showing the current project directory.
1122 * \since QGIS 3.0
1123 */
1124 class CORE_EXPORT QgsProjectHomeItem : public QgsDirectoryItem
1125 {
1126 Q_OBJECT
1127
1128 public:
1129
1130 QgsProjectHomeItem( QgsDataItem *parent, const QString &name, const QString &dirPath, const QString &path );
1131
1132 QIcon icon() override;
1133 QVariant sortKey() const override;
1134
1135 };
1136
1137 /**
1138 * \ingroup core
1139 * \brief A directory item showing the a single favorite directory.
1140 * \since QGIS 3.0
1141 */
1142 Q_NOWARN_DEPRECATED_PUSH // rename is deprecated
1143 class CORE_EXPORT QgsFavoriteItem : public QgsDirectoryItem
1144 {
1145 Q_OBJECT
1146
1147 public:
1148
1149 QgsFavoriteItem( QgsFavoritesItem *parent, const QString &name, const QString &dirPath, const QString &path );
1150
1151 bool rename( const QString &name ) override;
1152
1153 private:
1154
1155 QgsFavoritesItem *mFavorites = nullptr;
1156 };
1157 Q_NOWARN_DEPRECATED_POP
1158
1159 #endif
1160 ///@endcond
1161
1162 #endif // QGSDATAITEM_H
1163
1164
1165