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 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 ...
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.
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)