18 #include <QAbstractTextDocumentLayout>
19 #include <QHeaderView>
22 #include <QToolButton>
23 #include <QFileDialog>
24 #include <QPlainTextDocumentLayout>
25 #include <QSortFilterProxyModel>
33 #include "qgssettings.h"
38 #include "qgsnative.h"
49 #include <QDragEnterEvent>
54 , mModel( browserModel )
55 , mPropertiesWidgetEnabled( false )
56 , mPropertiesWidgetHeight( 0 )
60 mContents->layout()->setContentsMargins( 0, 0, 0, 0 );
61 static_cast< QVBoxLayout *
>( mContents->layout() )->setSpacing( 0 );
63 setWindowTitle( name );
65 mBrowserView =
new QgsDockBrowserTreeView(
this );
66 mLayoutBrowser->addWidget( mBrowserView );
68 mWidgetFilter->hide();
69 mLeFilter->setPlaceholderText( tr(
"Type here to filter visible items…" ) );
72 QMenu *menu =
new QMenu(
this );
73 menu->setSeparatorsCollapsible(
false );
74 mBtnFilterOptions->setMenu( menu );
75 QAction *action =
new QAction( tr(
"Case Sensitive" ), menu );
76 action->setData(
"case" );
77 action->setCheckable(
true );
78 action->setChecked(
false );
80 menu->addAction( action );
81 QActionGroup *group =
new QActionGroup( menu );
82 action =
new QAction( tr(
"Filter Pattern Syntax" ), group );
83 action->setSeparator(
true );
84 menu->addAction( action );
85 action =
new QAction( tr(
"Normal" ), group );
87 action->setCheckable(
true );
88 action->setChecked(
true );
89 menu->addAction( action );
90 action =
new QAction( tr(
"Wildcard(s)" ), group );
92 action->setCheckable(
true );
93 menu->addAction( action );
94 action =
new QAction( tr(
"Regular Expression" ), group );
96 action->setCheckable(
true );
97 menu->addAction( action );
99 mBrowserView->setExpandsOnDoubleClick(
false );
103 connect( mActionCollapse, &QAction::triggered, mBrowserView, &QgsDockBrowserTreeView::collapseAll );
111 connect( mBrowserView, &QgsDockBrowserTreeView::doubleClicked,
this, &QgsBrowserDockWidget::itemDoubleClicked );
119 QgsSettings settings;
120 settings.setValue( settingsSection() +
"/propertiesWidgetEnabled", mPropertiesWidgetEnabled );
122 settings.setValue( settingsSection() +
"/propertiesWidgetHeight", mPropertiesWidgetHeight );
137 mBrowserView->setSettingsSection( objectName().toLower() );
138 mBrowserView->setBrowserModel( mModel );
139 mBrowserView->setModel( mProxyModel );
140 mBrowserView->setSortingEnabled(
true );
141 mBrowserView->sortByColumn( 0, Qt::AscendingOrder );
143 mBrowserView->setTextElideMode( Qt::ElideNone );
144 mBrowserView->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
145 mBrowserView->header()->setStretchLastSection(
false );
148 connect( mBrowserView->selectionModel(), &QItemSelectionModel::selectionChanged,
157 QgsSettings settings;
158 mPropertiesWidgetEnabled = settings.value( settingsSection() +
"/propertiesWidgetEnabled",
false ).toBool();
159 mActionPropertiesWidget->setChecked( mPropertiesWidgetEnabled );
160 mPropertiesWidget->setVisible(
false );
162 mPropertiesWidgetHeight = settings.value( settingsSection() +
"/propertiesWidgetHeight" ).toFloat();
163 QList<int> sizes = mSplitter->sizes();
164 int total = sizes.value( 0 ) + sizes.value( 1 );
165 int height =
static_cast<int>( total * mPropertiesWidgetHeight );
167 sizes << total - height << height;
168 mSplitter->setSizes( sizes );
174 void QgsBrowserDockWidget::itemDoubleClicked(
const QModelIndex &index )
185 if ( provider->handleDoubleClick( item, context ) )
193 if ( mBrowserView->isExpanded( index ) )
194 mBrowserView->collapse( index );
196 mBrowserView->expand( index );
200 void QgsBrowserDockWidget::onOptionsChanged()
202 std::function< void(
const QModelIndex &index ) > updateItem;
203 updateItem = [
this, &updateItem](
const QModelIndex & index )
207 dirItem->reevaluateMonitoring();
210 const int rowCount = mModel->
rowCount( index );
211 for (
int i = 0; i < rowCount; ++i )
213 const QModelIndex child = mModel->
index( i, 0, index );
218 for (
int i = 0; i < mModel->
rowCount(); ++i )
220 updateItem( mModel->
index( i, 0 ) );
226 QModelIndex index = mProxyModel->mapToSource( mBrowserView->indexAt( pt ) );
231 const QModelIndexList selection = mBrowserView->selectionModel()->selectedIndexes();
232 QList< QgsDataItem * > selectedItems;
233 selectedItems.reserve( selection.size() );
234 for (
const QModelIndex &selectedIndex : selection )
238 selectedItems << selectedItem;
241 QMenu *menu =
new QMenu(
this );
243 const QList<QMenu *> menus = item->
menus( menu );
244 QList<QAction *> actions = item->
actions( menu );
246 if ( !menus.isEmpty() )
248 for ( QMenu *mn : menus )
254 if ( !actions.isEmpty() )
256 if ( !menu->actions().isEmpty() )
257 menu->addSeparator();
259 menu->addActions( actions );
267 provider->populateContextMenu( item, menu, selectedItems, context );
270 if ( menu->actions().isEmpty() )
276 menu->popup( mBrowserView->mapToGlobal( pt ) );
281 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
297 QString directory = QFileDialog::getExistingDirectory(
this, tr(
"Add directory to favorites" ) );
298 if ( !directory.isEmpty() )
324 mDisabledDataItemsKeys = filter;
334 mModel->
removeFavorite( mProxyModel->mapToSource( mBrowserView->currentIndex() ) );
339 refreshModel( QModelIndex() );
342 void QgsBrowserDockWidget::refreshModel(
const QModelIndex &index )
344 if ( mModel && mProxyModel )
361 for (
int i = 0; i < mModel->
rowCount( index ); i++ )
363 QModelIndex idx = mModel->
index( i, 0, index );
364 QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
384 void QgsBrowserDockWidget::addLayer(
QgsLayerItem *layerItem )
394 QgsDebugMsg( QStringLiteral(
"rowCount() = %1" ).arg( mModel->
rowCount( mProxyModel->mapToSource( index ) ) ) );
399 QgsProjectItem *projectItem = qobject_cast<QgsProjectItem *>( item );
402 QApplication::setOverrideCursor( Qt::WaitCursor );
403 emit
openFile( projectItem->
path(), QStringLiteral(
"project" ) );
404 QApplication::restoreOverrideCursor();
410 QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
413 QApplication::setOverrideCursor( Qt::WaitCursor );
414 addLayer( layerItem );
415 QApplication::restoreOverrideCursor();
424 QApplication::setOverrideCursor( Qt::WaitCursor );
427 QModelIndexList list = mBrowserView->selectionModel()->selectedIndexes();
428 std::sort( list.begin(), list.end() );
431 const auto constList = list;
432 for (
const QModelIndex &index : constList )
437 QgsProjectItem *projectItem = qobject_cast<QgsProjectItem *>( item );
439 emit
openFile( projectItem->
path(), QStringLiteral(
"project" ) );
441 QApplication::restoreOverrideCursor();
447 for (
int i = list.size() - 1; i >= 0; i-- )
452 QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
454 addLayer( layerItem );
458 QApplication::restoreOverrideCursor();
463 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
476 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
483 QgsBrowserPropertiesDialog *dialog =
new QgsBrowserPropertiesDialog( settingsSection(),
this );
484 dialog->setAttribute( Qt::WA_DeleteOnClose );
485 dialog->setItem( item, createContext() );
492 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
499 QgsSettings settings;
500 QStringList fastScanDirs = settings.value( QStringLiteral(
"qgis/scanItemsFastScanUris" ),
501 QStringList() ).toStringList();
502 int idx = fastScanDirs.indexOf( item->
path() );
505 fastScanDirs.removeAt( idx );
509 fastScanDirs << item->
path();
511 settings.setValue( QStringLiteral(
"qgis/scanItemsFastScanUris" ), fastScanDirs );
517 mWidgetFilter->setVisible( visible );
520 mLeFilter->setText( QString() );
525 mLeFilter->setFocus();
531 QString filter = mLeFilter->text();
544 if ( !action || ! mProxyModel )
557 int QgsBrowserDockWidget::selectedItemsCount()
559 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
560 if ( selectionModel )
562 return selectionModel->selectedIndexes().size();
577 Q_UNUSED( deselected )
578 if ( mPropertiesWidgetEnabled )
580 setPropertiesWidget();
584 void QgsBrowserDockWidget::clearPropertiesWidget()
586 while ( mPropertiesLayout->count() > 0 )
588 delete mPropertiesLayout->itemAt( 0 )->widget();
590 mPropertiesWidget->setVisible(
false );
593 void QgsBrowserDockWidget::setPropertiesWidget()
595 clearPropertiesWidget();
596 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
597 if ( selectionModel )
599 QModelIndexList indexes = selectionModel->selectedIndexes();
600 if ( indexes.size() == 1 )
602 QModelIndex index = mProxyModel->mapToSource( indexes.value( 0 ) );
605 QgsBrowserPropertiesWidget *propertiesWidget = QgsBrowserPropertiesWidget::createWidget( item, context, mPropertiesWidget );
606 if ( propertiesWidget )
608 propertiesWidget->setCondensedMode(
true );
609 mPropertiesLayout->addWidget( propertiesWidget );
613 mPropertiesWidget->setVisible( mPropertiesLayout->count() > 0 );
618 mPropertiesWidgetEnabled = enable;
619 if ( enable && selectedItemsCount() == 1 )
621 setPropertiesWidget();
625 clearPropertiesWidget();
631 if ( index.isValid() )
633 QModelIndex proxyIndex = mProxyModel->mapFromSource( index );
634 mBrowserView->expand( proxyIndex );
635 mBrowserView->setCurrentIndex( proxyIndex );
641 QList<int> sizes = mSplitter->sizes();
642 float total = sizes.value( 0 ) + sizes.value( 1 );
643 mPropertiesWidgetHeight = total > 0 ? sizes.value( 1 ) / total : 0;
@ 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.
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 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.
QString dirPath() const
Returns the full path to the directory the item represents.
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.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
#define QgsDebugMsgLevel(str, level)