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,
141 this, &QgsBrowserWidget::selectionChanged );
149 mActionPropertiesWidget->setChecked( settings.
value( settingsSection() +
"/propertiesWidgetEnabled",
false ).toBool() );
150 mPropertiesWidget->setVisible(
false );
152 mSplitter->restoreState( settings.
value( QStringLiteral(
"%1/splitterState" ).arg( settingsSection() ) ).toByteArray() );
155 QWidget::showEvent( e );
158void QgsBrowserWidget::itemDoubleClicked(
const QModelIndex &index )
169 if ( provider->handleDoubleClick( item, context ) )
177 if ( mBrowserView->isExpanded( index ) )
178 mBrowserView->collapse( index );
180 mBrowserView->expand( index );
184void QgsBrowserWidget::onOptionsChanged()
186 std::function< void(
const QModelIndex &index ) > updateItem;
187 updateItem = [
this, &updateItem](
const QModelIndex & index )
191 dirItem->reevaluateMonitoring();
194 const int rowCount = mModel->
rowCount( index );
195 for (
int i = 0; i < rowCount; ++i )
197 const QModelIndex child = mModel->
index( i, 0, index );
202 for (
int i = 0; i < mModel->
rowCount(); ++i )
204 updateItem( mModel->
index( i, 0 ) );
208void QgsBrowserWidget::showContextMenu( QPoint pt )
210 QModelIndex index = mProxyModel->mapToSource( mBrowserView->indexAt( pt ) );
215 const QModelIndexList selection = mBrowserView->selectionModel()->selectedIndexes();
216 QList< QgsDataItem * > selectedItems;
217 selectedItems.reserve( selection.size() );
218 for (
const QModelIndex &selectedIndex : selection )
222 selectedItems << selectedItem;
225 QMenu *menu =
new QMenu(
this );
227 const QList<QMenu *> menus = item->
menus( menu );
228 QList<QAction *> actions = item->
actions( menu );
230 if ( !menus.isEmpty() )
232 for ( QMenu *mn : menus )
238 if ( !actions.isEmpty() )
240 if ( !menu->actions().isEmpty() )
241 menu->addSeparator();
243 menu->addActions( actions );
251 return a->precedenceWhenPopulatingMenus() < b->precedenceWhenPopulatingMenus();
255 provider->populateContextMenu( item, menu, selectedItems, context );
258 if ( menu->actions().isEmpty() )
264 menu->popup( mBrowserView->mapToGlobal( pt ) );
280 mDisabledDataItemsKeys = filter;
290 refreshModel( QModelIndex() );
293void QgsBrowserWidget::refreshModel(
const QModelIndex &index )
295 if ( mModel && mProxyModel )
312 for (
int i = 0; i < mModel->
rowCount( index ); i++ )
314 QModelIndex idx = mModel->
index( i, 0, index );
315 QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
335void QgsBrowserWidget::addLayer(
QgsLayerItem *layerItem )
343void QgsBrowserWidget::addSelectedLayers()
345 QApplication::setOverrideCursor( Qt::WaitCursor );
348 QModelIndexList list = mBrowserView->selectionModel()->selectedIndexes();
349 std::sort( list.begin(), list.end() );
352 const auto constList = list;
353 for (
const QModelIndex &index : constList )
358 QgsProjectItem *projectItem = qobject_cast<QgsProjectItem *>( item );
360 emit
openFile( projectItem->
path(), QStringLiteral(
"project" ) );
362 QApplication::restoreOverrideCursor();
368 for (
int i = list.size() - 1; i >= 0; i-- )
373 QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
375 addLayer( layerItem );
379 QApplication::restoreOverrideCursor();
382void QgsBrowserWidget::hideItem()
384 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
395void QgsBrowserWidget::showProperties()
397 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
404 QgsBrowserPropertiesDialog *dialog =
new QgsBrowserPropertiesDialog( settingsSection(),
this );
405 dialog->setAttribute( Qt::WA_DeleteOnClose );
406 dialog->setItem( item, createContext() );
411void QgsBrowserWidget::showFilterWidget(
bool visible )
413 mWidgetFilter->setVisible( visible );
416 mLeFilter->setText( QString() );
421 mLeFilter->setFocus();
425void QgsBrowserWidget::setFilter()
427 QString filter = mLeFilter->text();
438void QgsBrowserWidget::setFilterSyntax( QAction *action )
440 if ( !action || ! mProxyModel )
446void QgsBrowserWidget::setCaseSensitive(
bool caseSensitive )
453int QgsBrowserWidget::selectedItemsCount()
455 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
456 if ( selectionModel )
458 return selectionModel->selectedIndexes().size();
467 context.
setView( mBrowserView );
471void QgsBrowserWidget::selectionChanged(
const QItemSelection &selected,
const QItemSelection &deselected )
474 Q_UNUSED( deselected )
475 if ( mActionPropertiesWidget->isChecked() )
477 setPropertiesWidget();
481void QgsBrowserWidget::clearPropertiesWidget()
483 while ( mPropertiesLayout->count() > 0 )
485 delete mPropertiesLayout->itemAt( 0 )->widget();
487 mPropertiesWidget->setVisible(
false );
490void QgsBrowserWidget::setPropertiesWidget()
492 clearPropertiesWidget();
493 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
494 if ( selectionModel )
496 QModelIndexList indexes = selectionModel->selectedIndexes();
497 if ( indexes.size() == 1 )
499 QModelIndex index = mProxyModel->mapToSource( indexes.value( 0 ) );
502 QgsBrowserPropertiesWidget *propertiesWidget = QgsBrowserPropertiesWidget::createWidget( item, context, mPropertiesWidget );
503 if ( propertiesWidget )
505 propertiesWidget->setCondensedMode(
true );
506 mPropertiesLayout->addWidget( propertiesWidget );
510 mPropertiesWidget->setVisible( mPropertiesLayout->count() > 0 );
513void QgsBrowserWidget::enablePropertiesWidget(
bool enable )
515 mActionPropertiesWidget->setChecked( enable );
516 propertiesWidgetToggled( enable );
519void QgsBrowserWidget::propertiesWidgetToggled(
bool enabled )
521 if ( enabled && selectedItemsCount() == 1 )
523 setPropertiesWidget();
527 clearPropertiesWidget();
531 settings.
setValue( settingsSection() +
"/propertiesWidgetEnabled", enabled );
536 if ( index.isValid() )
538 QModelIndex proxyIndex = mProxyModel->mapFromSource( index );
539 mBrowserView->expand( proxyIndex );
540 mBrowserView->setCurrentIndex( proxyIndex );
544void QgsBrowserWidget::splitterMoved()
547 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)