27#include <QActionGroup>
28#include <QDesktopServices>
29#include <QDialogButtonBox>
37#include "moc_qgsdatasourceselectdialog.cpp"
39using namespace Qt::StringLiterals;
43 bool setFilterByLayerType,
52 mBrowserModel->initialize();
56 mBrowserModel = browserModel;
62 mBrowserProxyModel.setBrowserModel( mBrowserModel );
63 mBrowserTreeView->setHeaderHidden(
true );
65 if ( setFilterByLayerType )
72 mBrowserTreeView->setModel( &mBrowserProxyModel );
73 mBrowserTreeView->setBrowserModel( mBrowserModel );
77 mBrowserTreeView->setBrowserModel( mBrowserModel );
79 mWidgetFilter->hide();
80 mLeFilter->setPlaceholderText( tr(
"Type here to filter visible items…" ) );
83 QMenu *menu =
new QMenu(
this );
84 menu->setSeparatorsCollapsible(
false );
85 mBtnFilterOptions->setMenu( menu );
86 QAction *action =
new QAction( tr(
"Case Sensitive" ), menu );
87 action->setData(
"case" );
88 action->setCheckable(
true );
89 action->setChecked(
false );
91 menu->addAction( action );
92 QActionGroup *group =
new QActionGroup( menu );
93 action =
new QAction( tr(
"Filter Pattern Syntax" ), group );
94 action->setSeparator(
true );
95 menu->addAction( action );
96 action =
new QAction( tr(
"Normal" ), group );
98 action->setCheckable(
true );
99 action->setChecked(
true );
100 menu->addAction( action );
101 action =
new QAction( tr(
"Wildcard(s)" ), group );
103 action->setCheckable(
true );
104 menu->addAction( action );
105 action =
new QAction( tr(
"Regular Expression" ), group );
107 action->setCheckable(
true );
108 menu->addAction( action );
110 connect( mActionRefresh, &QAction::triggered,
this, [
this] { refreshModel( QModelIndex() ); } );
111 connect( mBrowserTreeView, &QgsBrowserTreeView::clicked,
this, &QgsDataSourceSelectWidget::onLayerSelected );
112 connect( mBrowserTreeView, &QgsBrowserTreeView::doubleClicked,
this, &QgsDataSourceSelectWidget::itemDoubleClicked );
113 connect( mActionCollapse, &QAction::triggered, mBrowserTreeView, &QgsBrowserTreeView::collapseAll );
124 mActionShowFilter->trigger();
127 setAcceptDrops(
true );
134 QgsPanelWidget::showEvent( e );
136 if ( !lastSelectedPath.isEmpty() )
138 const QModelIndexList items = mBrowserProxyModel.match(
139 mBrowserProxyModel.index( 0, 0 ),
141 QVariant::fromValue( lastSelectedPath ),
145 if ( items.count() > 0 )
147 const QModelIndex expandIndex = items.at( 0 );
148 if ( expandIndex.isValid() )
150 mBrowserTreeView->scrollTo( expandIndex, QgsBrowserTreeView::ScrollHint::PositionAtTop );
151 mBrowserTreeView->expand( expandIndex );
157QString QgsDataSourceSelectWidget::acceptableFilePath( QDropEvent *event )
const
159 if ( event->mimeData()->hasUrls() )
161 const QList<QUrl> urls =
event->mimeData()->urls();
162 for (
const QUrl &url : urls )
164 const QString local = url.toLocalFile();
165 if ( local.isEmpty() )
168 if ( QFile::exists( local ) )
179 const QString filePath = acceptableFilePath( event );
180 if ( !filePath.isEmpty() )
182 event->acceptProposedAction();
192 const QString filePath = acceptableFilePath( event );
193 if ( !filePath.isEmpty() )
195 event->acceptProposedAction();
197 const QFileInfo fi( filePath );
212 mWidgetFilter->setVisible( visible );
215 mLeFilter->setText( QString() );
220 mLeFilter->setFocus();
226 if ( !description.isEmpty() )
228 if ( !mDescriptionLabel )
230 mDescriptionLabel =
new QLabel();
231 mDescriptionLabel->setWordWrap(
true );
232 mDescriptionLabel->setMargin( 4 );
233 mDescriptionLabel->setTextInteractionFlags( Qt::TextBrowserInteraction );
234 connect( mDescriptionLabel, &QLabel::linkActivated,
this, [](
const QString &link ) {
235 const QUrl url( link );
236 const QFileInfo file( url.toLocalFile() );
237 if ( file.exists() && !file.isDir() )
240 QDesktopServices::openUrl( url );
242 verticalLayout->insertWidget( 1, mDescriptionLabel );
244 mDescriptionLabel->setText( description );
248 if ( mDescriptionLabel )
250 verticalLayout->removeWidget( mDescriptionLabel );
251 delete mDescriptionLabel;
252 mDescriptionLabel =
nullptr;
259 mBrowserTreeView->expandPath( path, selectPath );
264 const QString filter = mLeFilter->text();
265 mBrowserProxyModel.setFilterString( filter );
268void QgsDataSourceSelectWidget::refreshModel(
const QModelIndex &index )
282 mBrowserModel->refresh( index );
285 for (
int i = 0; i < mBrowserModel->rowCount( index ); i++ )
287 const QModelIndex idx = mBrowserModel->index( i, 0, index );
288 const QModelIndex proxyIdx = mBrowserProxyModel.mapFromSource( idx );
289 QgsDataItem *child = mBrowserModel->dataItem( idx );
307void QgsDataSourceSelectWidget::setValid(
bool valid )
309 const bool prev = mIsValid;
311 if ( prev != mIsValid )
324 mBrowserProxyModel.setFilterCaseSensitivity( caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive );
329 mBrowserProxyModel.setFilterByLayerType(
true );
330 mBrowserProxyModel.setLayerType( layerType );
332 mBrowserTreeView->setModel( &mBrowserProxyModel );
333 mBrowserTreeView->setBrowserModel( mBrowserModel );
342void QgsDataSourceSelectWidget::onLayerSelected(
const QModelIndex &index )
344 bool isLayerCompatible =
false;
346 if ( index.isValid() )
351 const QgsLayerItem *layerItem = qobject_cast<const QgsLayerItem *>( dataItem );
354 isLayerCompatible =
true;
361 setValid( isLayerCompatible );
365void QgsDataSourceSelectWidget::itemDoubleClicked(
const QModelIndex &index )
367 onLayerSelected( index );
379 setWindowTitle( tr(
"Select a Data Source" ) );
380 setObjectName( u
"QgsDataSourceSelectDialog"_s );
385 QVBoxLayout *vl =
new QVBoxLayout();
386 vl->addWidget( mWidget, 1 );
387 vl->setContentsMargins( 4, 4, 4, 4 );
388 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
389 connect( buttonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
390 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
391 buttonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
398 vl->addWidget( buttonBox );
404 mWidget->setLayerTypeFilter( layerType );
409 mWidget->setDescription( description );
414 mWidget->expandPath( path, selectPath );
419 return mWidget->
uri();
424 mWidget->showFilterWidget( visible );
429 mWidget->setFilterSyntax( syntax );
434 mWidget->setCaseSensitive( caseSensitive );
439 mWidget->setFilter();
@ 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,...
LayerType
Types of layers that can be added to a map.
A model for showing available data sources and other items in a structured tree.
QgsDataItem * dataItem(const QModelIndex &idx) const
Returns the data item at the specified index, or nullptr if no item exists at the index.
void initialize()
Delayed initialization, needed because the provider registry must be already populated.
@ Path
Item path used to access path in the tree, see QgsDataItem::mPath.
FilterSyntax
Filter syntax options.
@ RegularExpression
Regular expression filtering.
@ Wildcards
Wildcard filtering.
@ Normal
Standard string filtering.
QgsDataItem * dataItem(const QModelIndex &index) const
Returns the data item at the specified proxy index, or nullptr if no item exists at the index.
bool filterByLayerType() const
Returns true if the model is filtered by map layer type.
Qgis::LayerType layerType() const
Returns the layer type to filter the model by.
Base class for all items in the model.
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.
void setFilter()
Apply filter to the model.
void showFilterWidget(bool visible)
Show/hide filter widget.
void setCaseSensitive(bool caseSensitive)
Sets filter case sensitivity.
void setFilterSyntax(QAction *)
Sets filter syntax.
QgsMimeDataUtils::Uri uri() const
Returns the (possibly invalid) uri of the selected data source.
void expandPath(const QString &path, bool selectPath=false)
Expands out a file path in the view.
void setDescription(const QString &description)
Sets a description label.
QgsDataSourceSelectDialog(QgsBrowserGuiModel *browserModel=nullptr, bool setFilterByLayerType=false, Qgis::LayerType layerType=Qgis::LayerType::Vector, QWidget *parent=nullptr)
Constructs a QgsDataSourceSelectDialog, optionally filtering by layer type.
void setLayerTypeFilter(Qgis::LayerType layerType)
Sets layer type filter to layerType and activates the filtering.
void cleared()
Emitted when the widget is cleared.
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
static QgsNative * nativePlatformInterface()
Returns the global native interface, which offers abstraction to the host OS's underlying public inte...
A browser item that represents a layer that can be opened with one of the providers.
Qgis::LayerType mapLayerType() const
Returns the associated map layer type.
QgsMimeDataUtils::UriList mimeUris() const override
Returns mime URIs for the data item, most data providers will only return a single URI but some data ...
Stores settings for use within QGIS.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
#define QgsDebugMsgLevel(str, level)
QString uri
Identifier of the data source recognized by its providerKey.