16#include "moc_qgsbrowserwidget.cpp" 
   18#include <QAbstractTextDocumentLayout> 
   24#include <QPlainTextDocumentLayout> 
   25#include <QSortFilterProxyModel> 
   26#include <QActionGroup> 
   51#include <QDragEnterEvent> 
   56  , mModel( browserModel )
 
   60  layout()->setContentsMargins( 0, 0, 0, 0 );
 
   61  qgis::down_cast<QVBoxLayout *>( layout() )->setSpacing( 0 );
 
   63  mBrowserView = 
new QgsDockBrowserTreeView( 
this );
 
   64  mLayoutBrowser->addWidget( mBrowserView );
 
   66  mWidgetFilter->hide();
 
   67  mLeFilter->setPlaceholderText( tr( 
"Type here to filter visible items…" ) );
 
   70  QMenu *menu = 
new QMenu( 
this );
 
   71  menu->setSeparatorsCollapsible( 
false );
 
   72  mBtnFilterOptions->setMenu( menu );
 
   73  QAction *action = 
new QAction( tr( 
"Case Sensitive" ), menu );
 
   74  action->setData( 
"case" );
 
   75  action->setCheckable( 
true );
 
   76  action->setChecked( 
false );
 
   77  connect( action, &QAction::toggled, 
this, &QgsBrowserWidget::setCaseSensitive );
 
   78  menu->addAction( action );
 
   79  QActionGroup *group = 
new QActionGroup( menu );
 
   80  action = 
new QAction( tr( 
"Filter Pattern Syntax" ), group );
 
   81  action->setSeparator( 
true );
 
   82  menu->addAction( action );
 
   83  action = 
new QAction( tr( 
"Normal" ), group );
 
   85  action->setCheckable( 
true );
 
   86  action->setChecked( 
true );
 
   87  menu->addAction( action );
 
   88  action = 
new QAction( tr( 
"Wildcard(s)" ), group );
 
   90  action->setCheckable( 
true );
 
   91  menu->addAction( action );
 
   92  action = 
new QAction( tr( 
"Regular Expression" ), group );
 
   94  action->setCheckable( 
true );
 
   95  menu->addAction( action );
 
   97  mBrowserView->setExpandsOnDoubleClick( 
false );
 
  100  connect( mActionAddLayers, &QAction::triggered, 
this, &QgsBrowserWidget::addSelectedLayers );
 
  101  connect( mActionCollapse, &QAction::triggered, mBrowserView, &QgsDockBrowserTreeView::collapseAll );
 
  102  connect( mActionShowFilter, &QAction::triggered, 
this, &QgsBrowserWidget::showFilterWidget );
 
  103  connect( mActionPropertiesWidget, &QAction::triggered, 
this, &QgsBrowserWidget::propertiesWidgetToggled );
 
  104  connect( mLeFilter, &QgsFilterLineEdit::returnPressed, 
this, &QgsBrowserWidget::setFilter );
 
  106  connect( mLeFilter, &QgsFilterLineEdit::textChanged, 
this, &QgsBrowserWidget::setFilter );
 
  107  connect( group, &QActionGroup::triggered, 
this, &QgsBrowserWidget::setFilterSyntax );
 
  108  connect( mBrowserView, &QgsDockBrowserTreeView::customContextMenuRequested, 
this, &QgsBrowserWidget::showContextMenu );
 
  109  connect( mBrowserView, &QgsDockBrowserTreeView::doubleClicked, 
this, &QgsBrowserWidget::itemDoubleClicked );
 
  110  connect( mSplitter, &QSplitter::splitterMoved, 
this, &QgsBrowserWidget::splitterMoved );
 
 
  129    mBrowserView->setSettingsSection( objectName().toLower() ); 
 
  130    mBrowserView->setBrowserModel( mModel );
 
  131    mBrowserView->setModel( mProxyModel );
 
  132    mBrowserView->setSortingEnabled( 
true );
 
  133    mBrowserView->sortByColumn( 0, Qt::AscendingOrder );
 
  135    mBrowserView->setTextElideMode( Qt::ElideNone );
 
  136    mBrowserView->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
 
  137    mBrowserView->header()->setStretchLastSection( 
false );
 
  140    connect( mBrowserView->selectionModel(), &QItemSelectionModel::selectionChanged, 
this, &QgsBrowserWidget::selectionChanged );
 
  147    mActionPropertiesWidget->setChecked( settings.
value( settingsSection() + 
"/propertiesWidgetEnabled", 
false ).toBool() );
 
  148    mPropertiesWidget->setVisible( 
false ); 
 
  150    mSplitter->restoreState( settings.
value( QStringLiteral( 
"%1/splitterState" ).arg( settingsSection() ) ).toByteArray() );
 
  153  QWidget::showEvent( e );
 
 
  156void QgsBrowserWidget::itemDoubleClicked( 
const QModelIndex &index )
 
  167    if ( provider->handleDoubleClick( item, context ) )
 
  175    if ( mBrowserView->isExpanded( index ) )
 
  176      mBrowserView->collapse( index );
 
  178      mBrowserView->expand( index );
 
  182void QgsBrowserWidget::onOptionsChanged()
 
  184  std::function<void( 
const QModelIndex &index )> updateItem;
 
  185  updateItem = [
this, &updateItem]( 
const QModelIndex &index ) {
 
  188      dirItem->reevaluateMonitoring();
 
  191    const int rowCount = mModel->
rowCount( index );
 
  192    for ( 
int i = 0; i < rowCount; ++i )
 
  194      const QModelIndex child = mModel->
index( i, 0, index );
 
  199  for ( 
int i = 0; i < mModel->
rowCount(); ++i )
 
  201    updateItem( mModel->
index( i, 0 ) );
 
  205void QgsBrowserWidget::showContextMenu( QPoint pt )
 
  207  QModelIndex index = mProxyModel->mapToSource( mBrowserView->indexAt( pt ) );
 
  212  const QModelIndexList selection = mBrowserView->selectionModel()->selectedIndexes();
 
  213  QList<QgsDataItem *> selectedItems;
 
  214  selectedItems.reserve( selection.size() );
 
  215  for ( 
const QModelIndex &selectedIndex : selection )
 
  219      selectedItems << selectedItem;
 
  222  QMenu *menu = 
new QMenu( 
this );
 
  224  const QList<QMenu *> menus = item->
menus( menu );
 
  225  QList<QAction *> actions = item->
actions( menu );
 
  227  if ( !menus.isEmpty() )
 
  229    for ( QMenu *mn : menus )
 
  235  if ( !actions.isEmpty() )
 
  237    if ( !menu->actions().isEmpty() )
 
  238      menu->addSeparator();
 
  240    menu->addActions( actions );
 
  247    return a->precedenceWhenPopulatingMenus() < b->precedenceWhenPopulatingMenus();
 
  251    provider->populateContextMenu( item, menu, selectedItems, context );
 
  254  if ( menu->actions().isEmpty() )
 
  260  menu->popup( mBrowserView->mapToGlobal( pt ) );
 
  287  mDisabledDataItemsKeys = filter;
 
 
  297  refreshModel( QModelIndex() );
 
 
  300void QgsBrowserWidget::refreshModel( 
const QModelIndex &index )
 
  302  if ( mModel && mProxyModel )
 
  319    for ( 
int i = 0; i < mModel->
rowCount( index ); i++ )
 
  321      QModelIndex idx = mModel->
index( i, 0, index );
 
  322      QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
 
  342void QgsBrowserWidget::addLayer( 
QgsLayerItem *layerItem )
 
  350void QgsBrowserWidget::addSelectedLayers()
 
  352  QApplication::setOverrideCursor( Qt::WaitCursor );
 
  355  QModelIndexList list = mBrowserView->selectionModel()->selectedIndexes();
 
  356  std::sort( list.begin(), list.end() );
 
  359  const auto constList = list;
 
  360  for ( 
const QModelIndex &index : constList )
 
  365      QgsProjectItem *projectItem = qobject_cast<QgsProjectItem *>( item );
 
  367        emit 
openFile( projectItem->
path(), QStringLiteral( 
"project" ) );
 
  369      QApplication::restoreOverrideCursor();
 
  375  for ( 
int i = list.size() - 1; i >= 0; i-- )
 
  380      QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
 
  382        addLayer( layerItem );
 
  386  QApplication::restoreOverrideCursor();
 
  389void QgsBrowserWidget::hideItem()
 
  391  QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
 
  402void QgsBrowserWidget::showProperties()
 
  404  QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
 
  411    QgsBrowserPropertiesDialog *dialog = 
new QgsBrowserPropertiesDialog( settingsSection(), 
this );
 
  412    dialog->setAttribute( Qt::WA_DeleteOnClose );
 
  413    dialog->setItem( item, createContext() );
 
  418void QgsBrowserWidget::showFilterWidget( 
bool visible )
 
  420  mWidgetFilter->setVisible( visible );
 
  423    mLeFilter->setText( QString() );
 
  428    mLeFilter->setFocus();
 
  432void QgsBrowserWidget::setFilter()
 
  434  QString filter = mLeFilter->text();
 
  445void QgsBrowserWidget::setFilterSyntax( QAction *action )
 
  447  if ( !action || !mProxyModel )
 
  453void QgsBrowserWidget::setCaseSensitive( 
bool caseSensitive )
 
  460int QgsBrowserWidget::selectedItemsCount()
 
  462  QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
 
  463  if ( selectionModel )
 
  465    return selectionModel->selectedIndexes().size();
 
  475  context.
setView( mBrowserView );
 
  479void QgsBrowserWidget::selectionChanged( 
const QItemSelection &selected, 
const QItemSelection &deselected )
 
  482  Q_UNUSED( deselected )
 
  483  if ( mActionPropertiesWidget->isChecked() )
 
  485    setPropertiesWidget();
 
  489void QgsBrowserWidget::clearPropertiesWidget()
 
  491  while ( mPropertiesLayout->count() > 0 )
 
  493    delete mPropertiesLayout->itemAt( 0 )->widget();
 
  495  mPropertiesWidget->setVisible( 
false );
 
  498void QgsBrowserWidget::setPropertiesWidget()
 
  500  clearPropertiesWidget();
 
  501  QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
 
  502  if ( selectionModel )
 
  504    QModelIndexList indexes = selectionModel->selectedIndexes();
 
  505    if ( indexes.size() == 1 )
 
  507      QModelIndex index = mProxyModel->mapToSource( indexes.value( 0 ) );
 
  510      QgsBrowserPropertiesWidget *propertiesWidget = QgsBrowserPropertiesWidget::createWidget( item, context, mPropertiesWidget );
 
  511      if ( propertiesWidget )
 
  513        propertiesWidget->setCondensedMode( 
true );
 
  514        mPropertiesLayout->addWidget( propertiesWidget );
 
  518  mPropertiesWidget->setVisible( mPropertiesLayout->count() > 0 );
 
  521void QgsBrowserWidget::enablePropertiesWidget( 
bool enable )
 
  523  mActionPropertiesWidget->setChecked( enable );
 
  524  propertiesWidgetToggled( enable );
 
  527void QgsBrowserWidget::propertiesWidgetToggled( 
bool enabled )
 
  529  if ( enabled && selectedItemsCount() == 1 )
 
  531    setPropertiesWidget();
 
  535    clearPropertiesWidget();
 
  539  settings.
setValue( settingsSection() + 
"/propertiesWidgetEnabled", enabled );
 
  544  if ( index.isValid() )
 
  546    QModelIndex proxyIndex = mProxyModel->mapFromSource( index );
 
  547    mBrowserView->expand( proxyIndex );
 
  548    mBrowserView->setCurrentIndex( proxyIndex );
 
 
  552void QgsBrowserWidget::splitterMoved()
 
  555  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 setMapCanvas(QgsMapCanvas *canvas)
Sets the associated map canvas that will be passed in QgsDataItemGuiContext to data items.
 
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 setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the data item.
 
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 browser item for directories: 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...
 
A browser 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 ...
 
Map canvas is a class for displaying all GIS data types on a canvas.
 
A bar for displaying non-blocking messages to the user.
 
Data item that can be used to represent QGIS projects.
 
Stores settings for use within QGIS.
 
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)