17 #include <QAbstractTextDocumentLayout> 
   18 #include <QHeaderView> 
   21 #include <QToolButton> 
   22 #include <QFileDialog> 
   23 #include <QPlainTextDocumentLayout> 
   24 #include <QSortFilterProxyModel> 
   25 #include <QActionGroup> 
   38 #include "qgsnative.h" 
   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::enablePropertiesWidget );
 
  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 );
 
  117   settings.
setValue( settingsSection() + 
"/propertiesWidgetEnabled", mPropertiesWidgetEnabled );
 
  119   settings.
setValue( settingsSection() + 
"/propertiesWidgetHeight", mPropertiesWidgetHeight );
 
  134     mBrowserView->setSettingsSection( objectName().toLower() ); 
 
  135     mBrowserView->setBrowserModel( mModel );
 
  136     mBrowserView->setModel( mProxyModel );
 
  137     mBrowserView->setSortingEnabled( 
true );
 
  138     mBrowserView->sortByColumn( 0, Qt::AscendingOrder );
 
  140     mBrowserView->setTextElideMode( Qt::ElideNone );
 
  141     mBrowserView->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
 
  142     mBrowserView->header()->setStretchLastSection( 
false );
 
  145     connect( mBrowserView->selectionModel(), &QItemSelectionModel::selectionChanged,
 
  146              this, &QgsBrowserWidget::selectionChanged );
 
  155     mPropertiesWidgetEnabled = settings.
value( settingsSection() + 
"/propertiesWidgetEnabled", 
false ).toBool();
 
  156     mActionPropertiesWidget->setChecked( mPropertiesWidgetEnabled );
 
  157     mPropertiesWidget->setVisible( 
false ); 
 
  159     mPropertiesWidgetHeight = settings.
value( settingsSection() + 
"/propertiesWidgetHeight" ).toFloat();
 
  160     QList<int> sizes = mSplitter->sizes();
 
  161     int total = sizes.value( 0 ) + sizes.value( 1 );
 
  162     int height = 
static_cast<int>( total * mPropertiesWidgetHeight );
 
  164     sizes << total - height << height;
 
  165     mSplitter->setSizes( sizes );
 
  168   QWidget::showEvent( e );
 
  171 void QgsBrowserWidget::itemDoubleClicked( 
const QModelIndex &index )
 
  182     if ( provider->handleDoubleClick( item, context ) )
 
  190     if ( mBrowserView->isExpanded( index ) )
 
  191       mBrowserView->collapse( index );
 
  193       mBrowserView->expand( index );
 
  197 void QgsBrowserWidget::onOptionsChanged()
 
  199   std::function< void( 
const QModelIndex &index ) > updateItem;
 
  200   updateItem = [
this, &updateItem]( 
const QModelIndex & index )
 
  204       dirItem->reevaluateMonitoring();
 
  207     const int rowCount = mModel->
rowCount( index );
 
  208     for ( 
int i = 0; i < rowCount; ++i )
 
  210       const QModelIndex child = mModel->
index( i, 0, index );
 
  215   for ( 
int i = 0; i < mModel->
rowCount(); ++i )
 
  217     updateItem( mModel->
index( i, 0 ) );
 
  221 void QgsBrowserWidget::showContextMenu( QPoint pt )
 
  223   QModelIndex index = mProxyModel->mapToSource( mBrowserView->indexAt( pt ) );
 
  228   const QModelIndexList selection = mBrowserView->selectionModel()->selectedIndexes();
 
  229   QList< QgsDataItem * > selectedItems;
 
  230   selectedItems.reserve( selection.size() );
 
  231   for ( 
const QModelIndex &selectedIndex : selection )
 
  235       selectedItems << selectedItem;
 
  238   QMenu *menu = 
new QMenu( 
this );
 
  240   const QList<QMenu *> menus = item->
menus( menu );
 
  241   QList<QAction *> actions = item->
actions( menu );
 
  243   if ( !menus.isEmpty() )
 
  245     for ( QMenu *mn : menus )
 
  251   if ( !actions.isEmpty() )
 
  253     if ( !menu->actions().isEmpty() )
 
  254       menu->addSeparator();
 
  256     menu->addActions( actions );
 
  264     return a->precedenceWhenPopulatingMenus() < b->precedenceWhenPopulatingMenus();
 
  268     provider->populateContextMenu( item, menu, selectedItems, context );
 
  271   if ( menu->actions().isEmpty() )
 
  277   menu->popup( mBrowserView->mapToGlobal( pt ) );
 
  293   mDisabledDataItemsKeys = filter;
 
  303   refreshModel( QModelIndex() );
 
  306 void QgsBrowserWidget::refreshModel( 
const QModelIndex &index )
 
  308   if ( mModel && mProxyModel )
 
  325     for ( 
int i = 0; i < mModel->
rowCount( index ); i++ )
 
  327       QModelIndex idx = mModel->
index( i, 0, index );
 
  328       QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
 
  348 void QgsBrowserWidget::addLayer( 
QgsLayerItem *layerItem )
 
  356 void QgsBrowserWidget::addSelectedLayers()
 
  358   QApplication::setOverrideCursor( Qt::WaitCursor );
 
  361   QModelIndexList list = mBrowserView->selectionModel()->selectedIndexes();
 
  362   std::sort( list.begin(), list.end() );
 
  365   const auto constList = list;
 
  366   for ( 
const QModelIndex &index : constList )
 
  371       QgsProjectItem *projectItem = qobject_cast<QgsProjectItem *>( item );
 
  373         emit 
openFile( projectItem->
path(), QStringLiteral( 
"project" ) );
 
  375       QApplication::restoreOverrideCursor();
 
  381   for ( 
int i = list.size() - 1; i >= 0; i-- )
 
  386       QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
 
  388         addLayer( layerItem );
 
  392   QApplication::restoreOverrideCursor();
 
  395 void QgsBrowserWidget::hideItem()
 
  397   QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
 
  408 void QgsBrowserWidget::showProperties()
 
  410   QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
 
  417     QgsBrowserPropertiesDialog *dialog = 
new QgsBrowserPropertiesDialog( settingsSection(), 
this );
 
  418     dialog->setAttribute( Qt::WA_DeleteOnClose );
 
  419     dialog->setItem( item, createContext() );
 
  424 void QgsBrowserWidget::showFilterWidget( 
bool visible )
 
  426   mWidgetFilter->setVisible( visible );
 
  429     mLeFilter->setText( QString() );
 
  434     mLeFilter->setFocus();
 
  438 void QgsBrowserWidget::setFilter()
 
  440   QString filter = mLeFilter->text();
 
  451 void QgsBrowserWidget::setFilterSyntax( QAction *action )
 
  453   if ( !action || ! mProxyModel )
 
  459 void QgsBrowserWidget::setCaseSensitive( 
bool caseSensitive )
 
  466 int QgsBrowserWidget::selectedItemsCount()
 
  468   QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
 
  469   if ( selectionModel )
 
  471     return selectionModel->selectedIndexes().size();
 
  483 void QgsBrowserWidget::selectionChanged( 
const QItemSelection &selected, 
const QItemSelection &deselected )
 
  486   Q_UNUSED( deselected )
 
  487   if ( mPropertiesWidgetEnabled )
 
  489     setPropertiesWidget();
 
  493 void QgsBrowserWidget::clearPropertiesWidget()
 
  495   while ( mPropertiesLayout->count() > 0 )
 
  497     delete mPropertiesLayout->itemAt( 0 )->widget();
 
  499   mPropertiesWidget->setVisible( 
false );
 
  502 void QgsBrowserWidget::setPropertiesWidget()
 
  504   clearPropertiesWidget();
 
  505   QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
 
  506   if ( selectionModel )
 
  508     QModelIndexList indexes = selectionModel->selectedIndexes();
 
  509     if ( indexes.size() == 1 )
 
  511       QModelIndex index = mProxyModel->mapToSource( indexes.value( 0 ) );
 
  514       QgsBrowserPropertiesWidget *propertiesWidget = QgsBrowserPropertiesWidget::createWidget( item, context, mPropertiesWidget );
 
  515       if ( propertiesWidget )
 
  517         propertiesWidget->setCondensedMode( 
true );
 
  518         mPropertiesLayout->addWidget( propertiesWidget );
 
  522   mPropertiesWidget->setVisible( mPropertiesLayout->count() > 0 );
 
  525 void QgsBrowserWidget::enablePropertiesWidget( 
bool enable )
 
  527   mPropertiesWidgetEnabled = enable;
 
  528   if ( enable && selectedItemsCount() == 1 )
 
  530     setPropertiesWidget();
 
  534     clearPropertiesWidget();
 
  540   if ( index.isValid() )
 
  542     QModelIndex proxyIndex = mProxyModel->mapFromSource( index );
 
  543     mBrowserView->expand( proxyIndex );
 
  544     mBrowserView->setCurrentIndex( proxyIndex );
 
  548 void QgsBrowserWidget::splitterMoved()
 
  550   QList<int> sizes = mSplitter->sizes();
 
  551   float total = sizes.value( 0 ) + sizes.value( 1 );
 
  552   mPropertiesWidgetHeight = total > 0 ? sizes.value( 1 ) / total : 0;
 
@ 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 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)