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 )
366 QgsDebugMsg( QStringLiteral(
"rowCount() = %1" ).arg( mModel->
rowCount( mProxyModel->mapToSource( index ) ) ) );
371 QgsProjectItem *projectItem = qobject_cast<QgsProjectItem *>( item );
374 QApplication::setOverrideCursor( Qt::WaitCursor );
375 emit
openFile( projectItem->
path(), QStringLiteral(
"project" ) );
376 QApplication::restoreOverrideCursor();
382 QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
385 QApplication::setOverrideCursor( Qt::WaitCursor );
386 addLayer( layerItem );
387 QApplication::restoreOverrideCursor();
396 QApplication::setOverrideCursor( Qt::WaitCursor );
399 QModelIndexList list = mBrowserView->selectionModel()->selectedIndexes();
400 std::sort( list.begin(), list.end() );
403 const auto constList = list;
404 for (
const QModelIndex &index : constList )
409 QgsProjectItem *projectItem = qobject_cast<QgsProjectItem *>( item );
411 emit
openFile( projectItem->
path(), QStringLiteral(
"project" ) );
413 QApplication::restoreOverrideCursor();
419 for (
int i = list.size() - 1; i >= 0; i-- )
424 QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
426 addLayer( layerItem );
430 QApplication::restoreOverrideCursor();
435 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
448 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
455 QgsBrowserPropertiesDialog *dialog =
new QgsBrowserPropertiesDialog( settingsSection(),
this );
456 dialog->setAttribute( Qt::WA_DeleteOnClose );
457 dialog->setItem( item, createContext() );
464 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
472 QStringList fastScanDirs = settings.
value( QStringLiteral(
"qgis/scanItemsFastScanUris" ),
473 QStringList() ).toStringList();
474 int idx = fastScanDirs.indexOf( item->
path() );
477 fastScanDirs.removeAt( idx );
481 fastScanDirs << item->
path();
483 settings.
setValue( QStringLiteral(
"qgis/scanItemsFastScanUris" ), fastScanDirs );
489 mWidgetFilter->setVisible( visible );
492 mLeFilter->setText( QString() );
497 mLeFilter->setFocus();
503 QString filter = mLeFilter->text();
516 if ( !action || ! mProxyModel )
529 int QgsBrowserDockWidget::selectedItemsCount()
531 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
532 if ( selectionModel )
534 return selectionModel->selectedIndexes().size();
549 Q_UNUSED( deselected )
550 if ( mPropertiesWidgetEnabled )
552 setPropertiesWidget();
556 void QgsBrowserDockWidget::clearPropertiesWidget()
558 while ( mPropertiesLayout->count() > 0 )
560 delete mPropertiesLayout->itemAt( 0 )->widget();
562 mPropertiesWidget->setVisible(
false );
565 void QgsBrowserDockWidget::setPropertiesWidget()
567 clearPropertiesWidget();
568 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
569 if ( selectionModel )
571 QModelIndexList indexes = selectionModel->selectedIndexes();
572 if ( indexes.size() == 1 )
574 QModelIndex index = mProxyModel->mapToSource( indexes.value( 0 ) );
577 QgsBrowserPropertiesWidget *propertiesWidget = QgsBrowserPropertiesWidget::createWidget( item, context, mPropertiesWidget );
578 if ( propertiesWidget )
580 propertiesWidget->setCondensedMode(
true );
581 mPropertiesLayout->addWidget( propertiesWidget );
585 mPropertiesWidget->setVisible( mPropertiesLayout->count() > 0 );
590 mPropertiesWidgetEnabled = enable;
591 if ( enable && selectedItemsCount() == 1 )
593 setPropertiesWidget();
597 clearPropertiesWidget();
603 if ( index.isValid() )
605 QModelIndex proxyIndex = mProxyModel->mapFromSource( index );
606 mBrowserView->expand( proxyIndex );
607 mBrowserView->setCurrentIndex( proxyIndex );
613 QList<int> sizes = mSplitter->sizes();
614 float total = sizes.value( 0 ) + sizes.value( 1 );
615 mPropertiesWidgetHeight = total > 0 ? sizes.value( 1 ) / total : 0;