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)