18 #include <QAbstractTextDocumentLayout>
19 #include <QHeaderView>
22 #include <QToolButton>
23 #include <QFileDialog>
24 #include <QPlainTextDocumentLayout>
25 #include <QSortFilterProxyModel>
38 #include "qgsnative.h"
46 #include <QDragEnterEvent>
50 , mModel( browserModel )
51 , mPropertiesWidgetEnabled( false )
52 , mPropertiesWidgetHeight( 0 )
56 mContents->layout()->setContentsMargins( 0, 0, 0, 0 );
57 static_cast< QVBoxLayout *
>( mContents->layout() )->setSpacing( 0 );
59 setWindowTitle( name );
61 mBrowserView =
new QgsDockBrowserTreeView(
this );
62 mLayoutBrowser->addWidget( mBrowserView );
64 mWidgetFilter->hide();
65 mLeFilter->setPlaceholderText( tr(
"Type here to filter visible items…" ) );
68 QMenu *menu =
new QMenu(
this );
69 menu->setSeparatorsCollapsible(
false );
70 mBtnFilterOptions->setMenu( menu );
71 QAction *action =
new QAction( tr(
"Case Sensitive" ), menu );
72 action->setData(
"case" );
73 action->setCheckable(
true );
74 action->setChecked(
false );
76 menu->addAction( action );
77 QActionGroup *group =
new QActionGroup( menu );
78 action =
new QAction( tr(
"Filter Pattern Syntax" ), group );
79 action->setSeparator(
true );
80 menu->addAction( action );
81 action =
new QAction( tr(
"Normal" ), group );
83 action->setCheckable(
true );
84 action->setChecked(
true );
85 menu->addAction( action );
86 action =
new QAction( tr(
"Wildcard(s)" ), group );
88 action->setCheckable(
true );
89 menu->addAction( action );
90 action =
new QAction( tr(
"Regular Expression" ), group );
92 action->setCheckable(
true );
93 menu->addAction( action );
95 mBrowserView->setExpandsOnDoubleClick(
false );
99 connect( mActionCollapse, &QAction::triggered, mBrowserView, &QgsDockBrowserTreeView::collapseAll );
107 connect( mBrowserView, &QgsDockBrowserTreeView::doubleClicked,
this, &QgsBrowserDockWidget::itemDoubleClicked );
114 settings.
setValue( settingsSection() +
"/propertiesWidgetEnabled", mPropertiesWidgetEnabled );
116 settings.
setValue( settingsSection() +
"/propertiesWidgetHeight", mPropertiesWidgetHeight );
131 mBrowserView->setSettingsSection( objectName().toLower() );
132 mBrowserView->setBrowserModel( mModel );
133 mBrowserView->setModel( mProxyModel );
134 mBrowserView->setSortingEnabled(
true );
135 mBrowserView->sortByColumn( 0, Qt::AscendingOrder );
137 mBrowserView->setTextElideMode( Qt::ElideNone );
138 mBrowserView->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
139 mBrowserView->header()->setStretchLastSection(
false );
142 connect( mBrowserView->selectionModel(), &QItemSelectionModel::selectionChanged,
152 mPropertiesWidgetEnabled = settings.
value( settingsSection() +
"/propertiesWidgetEnabled",
false ).toBool();
153 mActionPropertiesWidget->setChecked( mPropertiesWidgetEnabled );
154 mPropertiesWidget->setVisible(
false );
156 mPropertiesWidgetHeight = settings.
value( settingsSection() +
"/propertiesWidgetHeight" ).toFloat();
157 QList<int> sizes = mSplitter->sizes();
158 int total = sizes.value( 0 ) + sizes.value( 1 );
159 int height =
static_cast<int>( total * mPropertiesWidgetHeight );
161 sizes << total - height << height;
162 mSplitter->setSizes( sizes );
168 void QgsBrowserDockWidget::itemDoubleClicked(
const QModelIndex &index )
179 if ( provider->handleDoubleClick( item, context ) )
187 if ( mBrowserView->isExpanded( index ) )
188 mBrowserView->collapse( index );
190 mBrowserView->expand( index );
196 QModelIndex index = mProxyModel->mapToSource( mBrowserView->indexAt( pt ) );
201 const QModelIndexList selection = mBrowserView->selectionModel()->selectedIndexes();
202 QList< QgsDataItem * > selectedItems;
203 selectedItems.reserve( selection.size() );
204 for (
const QModelIndex &selectedIndex : selection )
208 selectedItems << selectedItem;
211 QMenu *menu =
new QMenu(
this );
213 const QList<QMenu *> menus = item->
menus( menu );
214 QList<QAction *> actions = item->
actions( menu );
216 if ( !menus.isEmpty() )
218 for ( QMenu *mn : menus )
224 if ( !actions.isEmpty() )
226 if ( !menu->actions().isEmpty() )
227 menu->addSeparator();
229 menu->addActions( actions );
237 provider->populateContextMenu( item, menu, selectedItems, context );
240 if ( menu->actions().isEmpty() )
246 menu->popup( mBrowserView->mapToGlobal( pt ) );
251 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
267 QString directory = QFileDialog::getExistingDirectory(
this, tr(
"Add directory to favorites" ) );
268 if ( !directory.isEmpty() )
294 mDisabledDataItemsKeys = filter;
304 mModel->
removeFavorite( mProxyModel->mapToSource( mBrowserView->currentIndex() ) );
309 refreshModel( QModelIndex() );
312 void QgsBrowserDockWidget::refreshModel(
const QModelIndex &index )
314 if ( mModel && mProxyModel )
331 for (
int i = 0; i < mModel->
rowCount( index ); i++ )
333 QModelIndex idx = mModel->
index( i, 0, index );
334 QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
339 if ( mBrowserView->isExpanded( proxyIdx ) || mBrowserView->hasExpandedDescendant( proxyIdx ) || ( child && child->
capabilities2() &
QgsDataItem::Fast ) )
354 void QgsBrowserDockWidget::addLayer(
QgsLayerItem *layerItem )
364 QgsDebugMsg( QStringLiteral(
"rowCount() = %1" ).arg( mModel->
rowCount( mProxyModel->mapToSource( index ) ) ) );
369 QgsProjectItem *projectItem = qobject_cast<QgsProjectItem *>( item );
372 QApplication::setOverrideCursor( Qt::WaitCursor );
373 emit
openFile( projectItem->
path(), QStringLiteral(
"project" ) );
374 QApplication::restoreOverrideCursor();
380 QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
383 QApplication::setOverrideCursor( Qt::WaitCursor );
384 addLayer( layerItem );
385 QApplication::restoreOverrideCursor();
394 QApplication::setOverrideCursor( Qt::WaitCursor );
397 QModelIndexList list = mBrowserView->selectionModel()->selectedIndexes();
398 std::sort( list.begin(), list.end() );
401 const auto constList = list;
402 for (
const QModelIndex &index : constList )
407 QgsProjectItem *projectItem = qobject_cast<QgsProjectItem *>( item );
409 emit
openFile( projectItem->
path(), QStringLiteral(
"project" ) );
411 QApplication::restoreOverrideCursor();
417 for (
int i = list.size() - 1; i >= 0; i-- )
422 QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
424 addLayer( layerItem );
428 QApplication::restoreOverrideCursor();
433 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
446 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
453 QgsBrowserPropertiesDialog *dialog =
new QgsBrowserPropertiesDialog( settingsSection(),
this );
454 dialog->setAttribute( Qt::WA_DeleteOnClose );
455 dialog->setItem( item, createContext() );
462 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
470 QStringList fastScanDirs = settings.
value( QStringLiteral(
"qgis/scanItemsFastScanUris" ),
471 QStringList() ).toStringList();
472 int idx = fastScanDirs.indexOf( item->
path() );
475 fastScanDirs.removeAt( idx );
479 fastScanDirs << item->
path();
481 settings.
setValue( QStringLiteral(
"qgis/scanItemsFastScanUris" ), fastScanDirs );
487 mWidgetFilter->setVisible( visible );
490 mLeFilter->setText( QString() );
495 mLeFilter->setFocus();
501 QString filter = mLeFilter->text();
514 if ( !action || ! mProxyModel )
527 int QgsBrowserDockWidget::selectedItemsCount()
529 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
530 if ( selectionModel )
532 return selectionModel->selectedIndexes().size();
547 Q_UNUSED( deselected )
548 if ( mPropertiesWidgetEnabled )
550 setPropertiesWidget();
554 void QgsBrowserDockWidget::clearPropertiesWidget()
556 while ( mPropertiesLayout->count() > 0 )
558 delete mPropertiesLayout->itemAt( 0 )->widget();
560 mPropertiesWidget->setVisible(
false );
563 void QgsBrowserDockWidget::setPropertiesWidget()
565 clearPropertiesWidget();
566 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
567 if ( selectionModel )
569 QModelIndexList indexes = selectionModel->selectedIndexes();
570 if ( indexes.size() == 1 )
572 QModelIndex index = mProxyModel->mapToSource( indexes.value( 0 ) );
575 QgsBrowserPropertiesWidget *propertiesWidget = QgsBrowserPropertiesWidget::createWidget( item, context, mPropertiesWidget );
576 if ( propertiesWidget )
578 propertiesWidget->setCondensedMode(
true );
579 mPropertiesLayout->addWidget( propertiesWidget );
583 mPropertiesWidget->setVisible( mPropertiesLayout->count() > 0 );
588 mPropertiesWidgetEnabled = enable;
589 if ( enable && selectedItemsCount() == 1 )
591 setPropertiesWidget();
595 clearPropertiesWidget();
601 if ( index.isValid() )
603 QModelIndex proxyIndex = mProxyModel->mapFromSource( index );
604 mBrowserView->expand( proxyIndex );
605 mBrowserView->setCurrentIndex( proxyIndex );
611 QList<int> sizes = mSplitter->sizes();
612 float total = sizes.value( 0 ) + sizes.value( 1 );
613 mPropertiesWidgetHeight = total > 0 ? sizes.value( 1 ) / total : 0;
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.
void addFavoriteDirectory(const QString &directory, const QString &name=QString())
Adds a directory to the favorites group.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
bool initialized() const
Returns true if the model has been initialized.
void removeFavorite(const QModelIndex &index)
Removes a favorite directory from its corresponding model index.
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 Capabilities capabilities2() const
Returns the capabilities for the data item.
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.
@ 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,...
virtual QList< QAction * > actions(QWidget *parent)
Returns the list of actions available for this item.
@ Project
Represents a QGIS project.
virtual void depopulate()
Remove children recursively and set as not populated. This is used when refreshing collapsed items.
A directory: contains subdirectories and layers.
QString dirPath() const
Returns the full path to the directory the item represents.
void cleared()
Emitted when the widget is cleared.
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 Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
#define QgsDebugMsgLevel(str, level)