18 #include <QAbstractTextDocumentLayout> 
   19 #include <QHeaderView> 
   22 #include <QToolButton> 
   23 #include <QFileDialog> 
   24 #include <QPlainTextDocumentLayout> 
   25 #include <QSortFilterProxyModel> 
   38 #include "qgsnative.h" 
   46 #include <QDragEnterEvent> 
   50   , mModel( browserModel )
 
   51   , mPropertiesWidgetEnabled( false )
 
   52   , mPropertiesWidgetHeight( 0 )
 
   56   mContents->layout()->setContentsMargins( 0, 0, 0, 0 );
 
   57   static_cast< QVBoxLayout * 
>( mContents->layout() )->setSpacing( 0 );
 
   59   setWindowTitle( name );
 
   61   mBrowserView = 
new QgsDockBrowserTreeView( 
this );
 
   62   mLayoutBrowser->addWidget( mBrowserView );
 
   64   mWidgetFilter->hide();
 
   65   mLeFilter->setPlaceholderText( tr( 
"Type here to filter visible items…" ) );
 
   68   QMenu *menu = 
new QMenu( 
this );
 
   69   menu->setSeparatorsCollapsible( 
false );
 
   70   mBtnFilterOptions->setMenu( menu );
 
   71   QAction *action = 
new QAction( tr( 
"Case Sensitive" ), menu );
 
   72   action->setData( 
"case" );
 
   73   action->setCheckable( 
true );
 
   74   action->setChecked( 
false );
 
   76   menu->addAction( action );
 
   77   QActionGroup *group = 
new QActionGroup( menu );
 
   78   action = 
new QAction( tr( 
"Filter Pattern Syntax" ), group );
 
   79   action->setSeparator( 
true );
 
   80   menu->addAction( action );
 
   81   action = 
new QAction( tr( 
"Normal" ), group );
 
   83   action->setCheckable( 
true );
 
   84   action->setChecked( 
true );
 
   85   menu->addAction( action );
 
   86   action = 
new QAction( tr( 
"Wildcard(s)" ), group );
 
   88   action->setCheckable( 
true );
 
   89   menu->addAction( action );
 
   90   action = 
new QAction( tr( 
"Regular Expression" ), group );
 
   92   action->setCheckable( 
true );
 
   93   menu->addAction( action );
 
   95   mBrowserView->setExpandsOnDoubleClick( 
false );
 
   99   connect( mActionCollapse, &QAction::triggered, mBrowserView, &QgsDockBrowserTreeView::collapseAll );
 
  107   connect( mBrowserView, &QgsDockBrowserTreeView::doubleClicked, 
this, &QgsBrowserDockWidget::itemDoubleClicked );
 
  114   settings.
setValue( settingsSection() + 
"/propertiesWidgetEnabled", mPropertiesWidgetEnabled );
 
  116   settings.
setValue( settingsSection() + 
"/propertiesWidgetHeight", mPropertiesWidgetHeight );
 
  131     mBrowserView->setSettingsSection( objectName().toLower() ); 
 
  132     mBrowserView->setBrowserModel( mModel );
 
  133     mBrowserView->setModel( mProxyModel );
 
  134     mBrowserView->setSortingEnabled( 
true );
 
  135     mBrowserView->sortByColumn( 0, Qt::AscendingOrder );
 
  137     mBrowserView->setTextElideMode( Qt::ElideNone );
 
  138     mBrowserView->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
 
  139     mBrowserView->header()->setStretchLastSection( 
false );
 
  142     connect( mBrowserView->selectionModel(), &QItemSelectionModel::selectionChanged,
 
  152     mPropertiesWidgetEnabled = settings.
value( settingsSection() + 
"/propertiesWidgetEnabled", 
false ).toBool();
 
  153     mActionPropertiesWidget->setChecked( mPropertiesWidgetEnabled );
 
  154     mPropertiesWidget->setVisible( 
false ); 
 
  156     mPropertiesWidgetHeight = settings.
value( settingsSection() + 
"/propertiesWidgetHeight" ).toFloat();
 
  157     QList<int> sizes = mSplitter->sizes();
 
  158     int total = sizes.value( 0 ) + sizes.value( 1 );
 
  159     int height = 
static_cast<int>( total * mPropertiesWidgetHeight );
 
  161     sizes << total - height << height;
 
  162     mSplitter->setSizes( sizes );
 
  168 void QgsBrowserDockWidget::itemDoubleClicked( 
const QModelIndex &index )
 
  179     if ( provider->handleDoubleClick( item, context ) )
 
  187     if ( mBrowserView->isExpanded( index ) )
 
  188       mBrowserView->collapse( index );
 
  190       mBrowserView->expand( index );
 
  196   QModelIndex index = mProxyModel->mapToSource( mBrowserView->indexAt( pt ) );
 
  201   const QModelIndexList selection = mBrowserView->selectionModel()->selectedIndexes();
 
  202   QList< QgsDataItem * > selectedItems;
 
  203   selectedItems.reserve( selection.size() );
 
  204   for ( 
const QModelIndex &selectedIndex : selection )
 
  208       selectedItems << selectedItem;
 
  211   QMenu *menu = 
new QMenu( 
this );
 
  213   const QList<QMenu *> menus = item->
menus( menu );
 
  214   QList<QAction *> actions = item->
actions( menu );
 
  216   if ( !menus.isEmpty() )
 
  218     for ( QMenu *mn : menus )
 
  224   if ( !actions.isEmpty() )
 
  226     if ( !menu->actions().isEmpty() )
 
  227       menu->addSeparator();
 
  229     menu->addActions( actions );
 
  237     provider->populateContextMenu( item, menu, selectedItems, context );
 
  240   if ( menu->actions().isEmpty() )
 
  246   menu->popup( mBrowserView->mapToGlobal( pt ) );
 
  251   QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
 
  267   QString directory = QFileDialog::getExistingDirectory( 
this, tr( 
"Add directory to favorites" ) );
 
  268   if ( !directory.isEmpty() )
 
  294   mDisabledDataItemsKeys = filter;
 
  304   mModel->
removeFavorite( mProxyModel->mapToSource( mBrowserView->currentIndex() ) );
 
  309   refreshModel( QModelIndex() );
 
  312 void QgsBrowserDockWidget::refreshModel( 
const QModelIndex &index )
 
  314   if ( mModel && mProxyModel )
 
  331     for ( 
int i = 0; i < mModel->
rowCount( index ); i++ )
 
  333       QModelIndex idx = mModel->
index( i, 0, index );
 
  334       QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
 
  339       if ( mBrowserView->isExpanded( proxyIdx ) || mBrowserView->hasExpandedDescendant( proxyIdx ) || ( child && child->
capabilities2() & 
QgsDataItem::Fast ) )
 
  354 void QgsBrowserDockWidget::addLayer( 
QgsLayerItem *layerItem )
 
  364   QgsDebugMsg( QStringLiteral( 
"rowCount() = %1" ).arg( mModel->
rowCount( mProxyModel->mapToSource( index ) ) ) );
 
  369     QgsProjectItem *projectItem = qobject_cast<QgsProjectItem *>( item );
 
  372       QApplication::setOverrideCursor( Qt::WaitCursor );
 
  373       emit 
openFile( projectItem->
path(), QStringLiteral( 
"project" ) );
 
  374       QApplication::restoreOverrideCursor();
 
  380     QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
 
  383       QApplication::setOverrideCursor( Qt::WaitCursor );
 
  384       addLayer( layerItem );
 
  385       QApplication::restoreOverrideCursor();
 
  394   QApplication::setOverrideCursor( Qt::WaitCursor );
 
  397   QModelIndexList list = mBrowserView->selectionModel()->selectedIndexes();
 
  398   std::sort( list.begin(), list.end() );
 
  401   const auto constList = list;
 
  402   for ( 
const QModelIndex &index : constList )
 
  407       QgsProjectItem *projectItem = qobject_cast<QgsProjectItem *>( item );
 
  409         emit 
openFile( projectItem->
path(), QStringLiteral( 
"project" ) );
 
  411       QApplication::restoreOverrideCursor();
 
  417   for ( 
int i = list.size() - 1; i >= 0; i-- )
 
  422       QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
 
  424         addLayer( layerItem );
 
  428   QApplication::restoreOverrideCursor();
 
  433   QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
 
  446   QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
 
  453     QgsBrowserPropertiesDialog *dialog = 
new QgsBrowserPropertiesDialog( settingsSection(), 
this );
 
  454     dialog->setAttribute( Qt::WA_DeleteOnClose );
 
  455     dialog->setItem( item, createContext() );
 
  462   QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
 
  470     QStringList fastScanDirs = settings.
value( QStringLiteral( 
"qgis/scanItemsFastScanUris" ),
 
  471                                QStringList() ).toStringList();
 
  472     int idx = fastScanDirs.indexOf( item->
path() );
 
  475       fastScanDirs.removeAt( idx );
 
  479       fastScanDirs << item->
path();
 
  481     settings.
setValue( QStringLiteral( 
"qgis/scanItemsFastScanUris" ), fastScanDirs );
 
  487   mWidgetFilter->setVisible( visible );
 
  490     mLeFilter->setText( QString() );
 
  495     mLeFilter->setFocus();
 
  501   QString filter = mLeFilter->text();
 
  514   if ( !action || ! mProxyModel )
 
  527 int QgsBrowserDockWidget::selectedItemsCount()
 
  529   QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
 
  530   if ( selectionModel )
 
  532     return selectionModel->selectedIndexes().size();
 
  547   Q_UNUSED( deselected )
 
  548   if ( mPropertiesWidgetEnabled )
 
  550     setPropertiesWidget();
 
  554 void QgsBrowserDockWidget::clearPropertiesWidget()
 
  556   while ( mPropertiesLayout->count() > 0 )
 
  558     delete mPropertiesLayout->itemAt( 0 )->widget();
 
  560   mPropertiesWidget->setVisible( 
false );
 
  563 void QgsBrowserDockWidget::setPropertiesWidget()
 
  565   clearPropertiesWidget();
 
  566   QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
 
  567   if ( selectionModel )
 
  569     QModelIndexList indexes = selectionModel->selectedIndexes();
 
  570     if ( indexes.size() == 1 )
 
  572       QModelIndex index = mProxyModel->mapToSource( indexes.value( 0 ) );
 
  575       QgsBrowserPropertiesWidget *propertiesWidget = QgsBrowserPropertiesWidget::createWidget( item, context, mPropertiesWidget );
 
  576       if ( propertiesWidget )
 
  578         propertiesWidget->setCondensedMode( 
true );
 
  579         mPropertiesLayout->addWidget( propertiesWidget );
 
  583   mPropertiesWidget->setVisible( mPropertiesLayout->count() > 0 );
 
  588   mPropertiesWidgetEnabled = enable;
 
  589   if ( enable && selectedItemsCount() == 1 )
 
  591     setPropertiesWidget();
 
  595     clearPropertiesWidget();
 
  601   if ( index.isValid() )
 
  603     QModelIndex proxyIndex = mProxyModel->mapFromSource( index );
 
  604     mBrowserView->expand( proxyIndex );
 
  605     mBrowserView->setCurrentIndex( proxyIndex );
 
  611   QList<int> sizes = mSplitter->sizes();
 
  612   float total = sizes.value( 0 ) + sizes.value( 1 );
 
  613   mPropertiesWidgetHeight = total > 0 ? sizes.value( 1 ) / total : 0;
 
A model for showing available data sources and other items in a structured tree.
void setMessageBar(QgsMessageBar *bar)
Sets message bar that will be passed in QgsDataItemGuiContext to data items.
void connectionsChanged(const QString &providerKey)
Emitted when connections for the specified providerKey have changed in the browser.
QgsDataItem * dataItem(const QModelIndex &idx) const
Returns the data item at the specified index, or nullptr if no item exists at the index.
void hidePath(QgsDataItem *item)
Hide the given path in the browser model.
void refresh(const QString &path)
Refresh item specified by path.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void initialize()
Delayed initialization, needed because the provider registry must be already populated.
void addFavoriteDirectory(const QString &directory, const QString &name=QString())
Adds a directory to the favorites group.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
bool initialized() const
Returns true if the model has been initialized.
void removeFavorite(const QModelIndex &index)
Removes a favorite directory from its corresponding model index.
A QSortFilterProxyModel subclass for filtering and sorting browser model items.
FilterSyntax
Filter syntax options.
@ RegularExpression
Regular expression filtering.
@ Wildcards
Wildcard filtering.
@ Normal
Standard string filtering.
void setHiddenDataItemProviderKeyFilter(const QStringList &hiddenItemsFilter)
Sets a filter to hide data items based on QgsDataItem::providerKey() associated with the item.
void setFilterString(const QString &filter)
Sets the filter string to use when filtering items in the model.
QgsDataItem * dataItem(const QModelIndex &index) const
Returns the data item at the specified proxy index, or nullptr if no item exists at the index.
void setFilterCaseSensitivity(Qt::CaseSensitivity sensitivity)
Sets whether item filtering should be case sensitive.
void setFilterSyntax(FilterSyntax syntax)
Sets the filter syntax.
void setBrowserModel(QgsBrowserModel *model)
Sets the underlying browser model.
Encapsulates the context in which a QgsDataItem is shown within the application GUI.
void setMessageBar(QgsMessageBar *bar)
Sets the associated message bar.
QList< QgsDataItemGuiProvider * > providers() const
Returns the list of available providers.
Abstract base class for providers which affect how QgsDataItem items behave within the application GU...
Base class for all items in the model.
virtual Capabilities capabilities2() const
Returns the capabilities for the data item.
virtual QList< QMenu * > menus(QWidget *parent)
Returns the list of menus available for this item.
virtual bool handleDoubleClick()
Called when a user double clicks on the item.
@ Fertile
Can create children. Even items without this capability may have children, but cannot create them,...
@ Fast
CreateChildren() is fast enough to be run in main thread when refreshing items, most root items (wms,...
virtual QList< QAction * > actions(QWidget *parent)
Returns the list of actions available for this item.
@ Project
Represents a QGIS project.
virtual void depopulate()
Remove children recursively and set as not populated. This is used when refreshing collapsed items.
A directory: contains subdirectories and layers.
QString dirPath() const
Returns the full path to the directory the item represents.
void cleared()
Emitted when the widget is cleared.
static QgsGui * instance()
Returns a pointer to the singleton instance.
static QgsDataItemGuiProviderRegistry * dataItemGuiProviderRegistry()
Returns the global data item GUI provider registry, used for tracking providers which affect the brow...
Item that represents a layer that can be opened with one of the providers.
QgsMimeDataUtils::UriList mimeUris() const override
Returns mime URIs for the data item, most data providers will only return a single URI but some data ...
A bar for displaying non-blocking messages to the user.
Data item that can be used to represent QGIS projects.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
#define QgsDebugMsgLevel(str, level)