17#include <QAbstractTextDocumentLayout> 
   23#include <QPlainTextDocumentLayout> 
   24#include <QSortFilterProxyModel> 
   25#include <QActionGroup> 
   50#include <QDragEnterEvent> 
   55  , mModel( browserModel )
 
   59  layout()->setContentsMargins( 0, 0, 0, 0 );
 
   60  qgis::down_cast< QVBoxLayout * >( layout() )->setSpacing( 0 );
 
   62  mBrowserView = 
new QgsDockBrowserTreeView( 
this );
 
   63  mLayoutBrowser->addWidget( mBrowserView );
 
   65  mWidgetFilter->hide();
 
   66  mLeFilter->setPlaceholderText( tr( 
"Type here to filter visible items…" ) );
 
   69  QMenu *menu = 
new QMenu( 
this );
 
   70  menu->setSeparatorsCollapsible( 
false );
 
   71  mBtnFilterOptions->setMenu( menu );
 
   72  QAction *action = 
new QAction( tr( 
"Case Sensitive" ), menu );
 
   73  action->setData( 
"case" );
 
   74  action->setCheckable( 
true );
 
   75  action->setChecked( 
false );
 
   76  connect( action, &QAction::toggled, 
this, &QgsBrowserWidget::setCaseSensitive );
 
   77  menu->addAction( action );
 
   78  QActionGroup *group = 
new QActionGroup( menu );
 
   79  action = 
new QAction( tr( 
"Filter Pattern Syntax" ), group );
 
   80  action->setSeparator( 
true );
 
   81  menu->addAction( action );
 
   82  action = 
new QAction( tr( 
"Normal" ), group );
 
   84  action->setCheckable( 
true );
 
   85  action->setChecked( 
true );
 
   86  menu->addAction( action );
 
   87  action = 
new QAction( tr( 
"Wildcard(s)" ), group );
 
   89  action->setCheckable( 
true );
 
   90  menu->addAction( action );
 
   91  action = 
new QAction( tr( 
"Regular Expression" ), group );
 
   93  action->setCheckable( 
true );
 
   94  menu->addAction( action );
 
   96  mBrowserView->setExpandsOnDoubleClick( 
false );
 
   99  connect( mActionAddLayers, &QAction::triggered, 
this, &QgsBrowserWidget::addSelectedLayers );
 
  100  connect( mActionCollapse, &QAction::triggered, mBrowserView, &QgsDockBrowserTreeView::collapseAll );
 
  101  connect( mActionShowFilter, &QAction::triggered, 
this, &QgsBrowserWidget::showFilterWidget );
 
  102  connect( mActionPropertiesWidget, &QAction::triggered, 
this, &QgsBrowserWidget::propertiesWidgetToggled );
 
  103  connect( mLeFilter, &QgsFilterLineEdit::returnPressed, 
this, &QgsBrowserWidget::setFilter );
 
  105  connect( mLeFilter, &QgsFilterLineEdit::textChanged, 
this, &QgsBrowserWidget::setFilter );
 
  106  connect( group, &QActionGroup::triggered, 
this, &QgsBrowserWidget::setFilterSyntax );
 
  107  connect( mBrowserView, &QgsDockBrowserTreeView::customContextMenuRequested, 
this, &QgsBrowserWidget::showContextMenu );
 
  108  connect( mBrowserView, &QgsDockBrowserTreeView::doubleClicked, 
this, &QgsBrowserWidget::itemDoubleClicked );
 
  109  connect( mSplitter, &QSplitter::splitterMoved, 
this, &QgsBrowserWidget::splitterMoved );
 
  128    mBrowserView->setSettingsSection( objectName().toLower() ); 
 
  129    mBrowserView->setBrowserModel( mModel );
 
  130    mBrowserView->setModel( mProxyModel );
 
  131    mBrowserView->setSortingEnabled( 
true );
 
  132    mBrowserView->sortByColumn( 0, Qt::AscendingOrder );
 
  134    mBrowserView->setTextElideMode( Qt::ElideNone );
 
  135    mBrowserView->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
 
  136    mBrowserView->header()->setStretchLastSection( 
false );
 
  139    connect( mBrowserView->selectionModel(), &QItemSelectionModel::selectionChanged,
 
  140             this, &QgsBrowserWidget::selectionChanged );
 
  148    mActionPropertiesWidget->setChecked( settings.
value( settingsSection() + 
"/propertiesWidgetEnabled", 
false ).toBool() );
 
  149    mPropertiesWidget->setVisible( 
false ); 
 
  151    mSplitter->restoreState( settings.
value( QStringLiteral( 
"%1/splitterState" ).arg( settingsSection() ) ).toByteArray() );
 
  154  QWidget::showEvent( e );
 
  157void QgsBrowserWidget::itemDoubleClicked( 
const QModelIndex &index )
 
  168    if ( provider->handleDoubleClick( item, context ) )
 
  176    if ( mBrowserView->isExpanded( index ) )
 
  177      mBrowserView->collapse( index );
 
  179      mBrowserView->expand( index );
 
  183void QgsBrowserWidget::onOptionsChanged()
 
  185  std::function< void( 
const QModelIndex &index ) > updateItem;
 
  186  updateItem = [
this, &updateItem]( 
const QModelIndex & index )
 
  190      dirItem->reevaluateMonitoring();
 
  193    const int rowCount = mModel->
rowCount( index );
 
  194    for ( 
int i = 0; i < rowCount; ++i )
 
  196      const QModelIndex child = mModel->
index( i, 0, index );
 
  201  for ( 
int i = 0; i < mModel->
rowCount(); ++i )
 
  203    updateItem( mModel->
index( i, 0 ) );
 
  207void QgsBrowserWidget::showContextMenu( QPoint pt )
 
  209  QModelIndex index = mProxyModel->mapToSource( mBrowserView->indexAt( pt ) );
 
  214  const QModelIndexList selection = mBrowserView->selectionModel()->selectedIndexes();
 
  215  QList< QgsDataItem * > selectedItems;
 
  216  selectedItems.reserve( selection.size() );
 
  217  for ( 
const QModelIndex &selectedIndex : selection )
 
  221      selectedItems << selectedItem;
 
  224  QMenu *menu = 
new QMenu( 
this );
 
  226  const QList<QMenu *> menus = item->
menus( menu );
 
  227  QList<QAction *> actions = item->
actions( menu );
 
  229  if ( !menus.isEmpty() )
 
  231    for ( QMenu *mn : menus )
 
  237  if ( !actions.isEmpty() )
 
  239    if ( !menu->actions().isEmpty() )
 
  240      menu->addSeparator();
 
  242    menu->addActions( actions );
 
  250    return a->precedenceWhenPopulatingMenus() < b->precedenceWhenPopulatingMenus();
 
  254    provider->populateContextMenu( item, menu, selectedItems, context );
 
  257  if ( menu->actions().isEmpty() )
 
  263  menu->popup( mBrowserView->mapToGlobal( pt ) );
 
  279  mDisabledDataItemsKeys = filter;
 
  289  refreshModel( QModelIndex() );
 
  292void QgsBrowserWidget::refreshModel( 
const QModelIndex &index )
 
  294  if ( mModel && mProxyModel )
 
  311    for ( 
int i = 0; i < mModel->
rowCount( index ); i++ )
 
  313      QModelIndex idx = mModel->
index( i, 0, index );
 
  314      QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
 
  334void QgsBrowserWidget::addLayer( 
QgsLayerItem *layerItem )
 
  342void QgsBrowserWidget::addSelectedLayers()
 
  344  QApplication::setOverrideCursor( Qt::WaitCursor );
 
  347  QModelIndexList list = mBrowserView->selectionModel()->selectedIndexes();
 
  348  std::sort( list.begin(), list.end() );
 
  351  const auto constList = list;
 
  352  for ( 
const QModelIndex &index : constList )
 
  357      QgsProjectItem *projectItem = qobject_cast<QgsProjectItem *>( item );
 
  359        emit 
openFile( projectItem->
path(), QStringLiteral( 
"project" ) );
 
  361      QApplication::restoreOverrideCursor();
 
  367  for ( 
int i = list.size() - 1; i >= 0; i-- )
 
  372      QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
 
  374        addLayer( layerItem );
 
  378  QApplication::restoreOverrideCursor();
 
  381void QgsBrowserWidget::hideItem()
 
  383  QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
 
  394void QgsBrowserWidget::showProperties()
 
  396  QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
 
  403    QgsBrowserPropertiesDialog *dialog = 
new QgsBrowserPropertiesDialog( settingsSection(), 
this );
 
  404    dialog->setAttribute( Qt::WA_DeleteOnClose );
 
  405    dialog->setItem( item, createContext() );
 
  410void QgsBrowserWidget::showFilterWidget( 
bool visible )
 
  412  mWidgetFilter->setVisible( visible );
 
  415    mLeFilter->setText( QString() );
 
  420    mLeFilter->setFocus();
 
  424void QgsBrowserWidget::setFilter()
 
  426  QString filter = mLeFilter->text();
 
  437void QgsBrowserWidget::setFilterSyntax( QAction *action )
 
  439  if ( !action || ! mProxyModel )
 
  445void QgsBrowserWidget::setCaseSensitive( 
bool caseSensitive )
 
  452int QgsBrowserWidget::selectedItemsCount()
 
  454  QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
 
  455  if ( selectionModel )
 
  457    return selectionModel->selectedIndexes().size();
 
  466  context.
setView( mBrowserView );
 
  470void QgsBrowserWidget::selectionChanged( 
const QItemSelection &selected, 
const QItemSelection &deselected )
 
  473  Q_UNUSED( deselected )
 
  474  if ( mActionPropertiesWidget->isChecked() )
 
  476    setPropertiesWidget();
 
  480void QgsBrowserWidget::clearPropertiesWidget()
 
  482  while ( mPropertiesLayout->count() > 0 )
 
  484    delete mPropertiesLayout->itemAt( 0 )->widget();
 
  486  mPropertiesWidget->setVisible( 
false );
 
  489void QgsBrowserWidget::setPropertiesWidget()
 
  491  clearPropertiesWidget();
 
  492  QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
 
  493  if ( selectionModel )
 
  495    QModelIndexList indexes = selectionModel->selectedIndexes();
 
  496    if ( indexes.size() == 1 )
 
  498      QModelIndex index = mProxyModel->mapToSource( indexes.value( 0 ) );
 
  501      QgsBrowserPropertiesWidget *propertiesWidget = QgsBrowserPropertiesWidget::createWidget( item, context, mPropertiesWidget );
 
  502      if ( propertiesWidget )
 
  504        propertiesWidget->setCondensedMode( 
true );
 
  505        mPropertiesLayout->addWidget( propertiesWidget );
 
  509  mPropertiesWidget->setVisible( mPropertiesLayout->count() > 0 );
 
  512void QgsBrowserWidget::enablePropertiesWidget( 
bool enable )
 
  514  mActionPropertiesWidget->setChecked( enable );
 
  515  propertiesWidgetToggled( enable );
 
  518void QgsBrowserWidget::propertiesWidgetToggled( 
bool enabled )
 
  520  if ( enabled && selectedItemsCount() == 1 )
 
  522    setPropertiesWidget();
 
  526    clearPropertiesWidget();
 
  530  settings.
setValue( settingsSection() + 
"/propertiesWidgetEnabled", enabled );
 
  535  if ( index.isValid() )
 
  537    QModelIndex proxyIndex = mProxyModel->mapFromSource( index );
 
  538    mBrowserView->expand( proxyIndex );
 
  539    mBrowserView->setCurrentIndex( proxyIndex );
 
  543void QgsBrowserWidget::splitterMoved()
 
  546  settings.
setValue( QStringLiteral( 
"%1/splitterState" ).arg( settingsSection() ), mSplitter->saveState() );
 
@ 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,...
 
@ Layer
Represents a map layer.
 
@ Project
Represents a QGIS project.
 
@ Directory
Represents a file directory.
 
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.
 
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
 
bool initialized() const
Returns true if the model has been initialized.
 
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 setView(QgsBrowserTreeView *view)
Sets the associated view.
 
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 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.
 
Qgis::BrowserItemType type() const
 
virtual QList< QAction * > actions(QWidget *parent)
Returns the list of actions available for this item.
 
virtual Qgis::BrowserItemCapabilities capabilities2() const
Returns the capabilities for the data item.
 
virtual void depopulate()
Remove children recursively and set as not populated. This is used when refreshing collapsed items.
 
A directory: contains subdirectories and layers.
 
void cleared()
Emitted when the widget is cleared.
 
void optionsChanged()
This signal is emitted whenever the application options have been changed.
 
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 QgsDebugMsgLevel(str, level)