27#include <QActionGroup>
28#include <QDesktopServices>
29#include <QDialogButtonBox>
37#include "moc_qgsdatasourceselectdialog.cpp"
39using namespace Qt::StringLiterals;
47 mBrowserModel->initialize();
51 mBrowserModel = browserModel;
57 mBrowserProxyModel.setBrowserModel( mBrowserModel );
58 mBrowserTreeView->setHeaderHidden(
true );
60 if ( setFilterByLayerType )
67 mBrowserTreeView->setModel( &mBrowserProxyModel );
68 mBrowserTreeView->setBrowserModel( mBrowserModel );
72 mBrowserTreeView->setBrowserModel( mBrowserModel );
74 mWidgetFilter->hide();
75 mLeFilter->setPlaceholderText( tr(
"Type here to filter visible items…" ) );
78 QMenu *menu =
new QMenu(
this );
79 menu->setSeparatorsCollapsible(
false );
80 mBtnFilterOptions->setMenu( menu );
81 QAction *action =
new QAction( tr(
"Case Sensitive" ), menu );
82 action->setData(
"case" );
83 action->setCheckable(
true );
84 action->setChecked(
false );
86 menu->addAction( action );
87 QActionGroup *group =
new QActionGroup( menu );
88 action =
new QAction( tr(
"Filter Pattern Syntax" ), group );
89 action->setSeparator(
true );
90 menu->addAction( action );
91 action =
new QAction( tr(
"Normal" ), group );
93 action->setCheckable(
true );
94 action->setChecked(
true );
95 menu->addAction( action );
96 action =
new QAction( tr(
"Wildcard(s)" ), group );
98 action->setCheckable(
true );
99 menu->addAction( action );
100 action =
new QAction( tr(
"Regular Expression" ), group );
102 action->setCheckable(
true );
103 menu->addAction( action );
105 connect( mActionRefresh, &QAction::triggered,
this, [
this] { refreshModel( QModelIndex() ); } );
106 connect( mBrowserTreeView, &QgsBrowserTreeView::clicked,
this, &QgsDataSourceSelectWidget::onLayerSelected );
107 connect( mBrowserTreeView, &QgsBrowserTreeView::doubleClicked,
this, &QgsDataSourceSelectWidget::itemDoubleClicked );
108 connect( mActionCollapse, &QAction::triggered, mBrowserTreeView, &QgsBrowserTreeView::collapseAll );
119 mActionShowFilter->trigger();
122 setAcceptDrops(
true );
129 QgsPanelWidget::showEvent( e );
131 if ( !lastSelectedPath.isEmpty() )
133 const QModelIndexList items
134 = mBrowserProxyModel.match( mBrowserProxyModel.index( 0, 0 ),
static_cast<int>(
QgsBrowserModel::CustomRole::Path ), QVariant::fromValue( lastSelectedPath ), 1, Qt::MatchRecursive );
135 if ( items.count() > 0 )
137 const QModelIndex expandIndex = items.at( 0 );
138 if ( expandIndex.isValid() )
140 mBrowserTreeView->scrollTo( expandIndex, QgsBrowserTreeView::ScrollHint::PositionAtTop );
141 mBrowserTreeView->expand( expandIndex );
147QString QgsDataSourceSelectWidget::acceptableFilePath( QDropEvent *event )
const
149 if ( event->mimeData()->hasUrls() )
151 const QList<QUrl> urls =
event->mimeData()->urls();
152 for (
const QUrl &url : urls )
154 const QString local = url.toLocalFile();
155 if ( local.isEmpty() )
158 if ( QFile::exists( local ) )
169 const QString filePath = acceptableFilePath( event );
170 if ( !filePath.isEmpty() )
172 event->acceptProposedAction();
182 const QString filePath = acceptableFilePath( event );
183 if ( !filePath.isEmpty() )
185 event->acceptProposedAction();
187 const QFileInfo fi( filePath );
202 mWidgetFilter->setVisible( visible );
205 mLeFilter->setText( QString() );
210 mLeFilter->setFocus();
216 if ( !description.isEmpty() )
218 if ( !mDescriptionLabel )
220 mDescriptionLabel =
new QLabel();
221 mDescriptionLabel->setWordWrap(
true );
222 mDescriptionLabel->setMargin( 4 );
223 mDescriptionLabel->setTextInteractionFlags( Qt::TextBrowserInteraction );
224 connect( mDescriptionLabel, &QLabel::linkActivated,
this, [](
const QString &link ) {
225 const QUrl url( link );
226 const QFileInfo file( url.toLocalFile() );
227 if ( file.exists() && !file.isDir() )
230 QDesktopServices::openUrl( url );
232 verticalLayout->insertWidget( 1, mDescriptionLabel );
234 mDescriptionLabel->setText( description );
238 if ( mDescriptionLabel )
240 verticalLayout->removeWidget( mDescriptionLabel );
241 delete mDescriptionLabel;
242 mDescriptionLabel =
nullptr;
249 mBrowserTreeView->expandPath( path, selectPath );
254 const QString filter = mLeFilter->text();
255 mBrowserProxyModel.setFilterString( filter );
258void QgsDataSourceSelectWidget::refreshModel(
const QModelIndex &index )
272 mBrowserModel->refresh( index );
275 for (
int i = 0; i < mBrowserModel->rowCount( index ); i++ )
277 const QModelIndex idx = mBrowserModel->index( i, 0, index );
278 const QModelIndex proxyIdx = mBrowserProxyModel.mapFromSource( idx );
279 QgsDataItem *child = mBrowserModel->dataItem( idx );
297void QgsDataSourceSelectWidget::setValid(
bool valid )
299 const bool prev = mIsValid;
301 if ( prev != mIsValid )
314 mBrowserProxyModel.setFilterCaseSensitivity( caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive );
319 mBrowserProxyModel.setFilterByLayerType(
true );
320 mBrowserProxyModel.setLayerType( layerType );
322 mBrowserTreeView->setModel( &mBrowserProxyModel );
323 mBrowserTreeView->setBrowserModel( mBrowserModel );
332void QgsDataSourceSelectWidget::onLayerSelected(
const QModelIndex &index )
334 bool isLayerCompatible =
false;
336 if ( index.isValid() )
341 const QgsLayerItem *layerItem = qobject_cast<const QgsLayerItem *>( dataItem );
344 isLayerCompatible =
true;
351 setValid( isLayerCompatible );
355void QgsDataSourceSelectWidget::itemDoubleClicked(
const QModelIndex &index )
357 onLayerSelected( index );
369 setWindowTitle( tr(
"Select a Data Source" ) );
370 setObjectName( u
"QgsDataSourceSelectDialog"_s );
375 QVBoxLayout *vl =
new QVBoxLayout();
376 vl->addWidget( mWidget, 1 );
377 vl->setContentsMargins( 4, 4, 4, 4 );
378 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
379 connect( buttonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
380 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
381 buttonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
388 vl->addWidget( buttonBox );
394 mWidget->setLayerTypeFilter( layerType );
399 mWidget->setDescription( description );
404 mWidget->expandPath( path, selectPath );
409 return mWidget->
uri();
414 mWidget->showFilterWidget( visible );
419 mWidget->setFilterSyntax( syntax );
424 mWidget->setCaseSensitive( caseSensitive );
429 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.