17 #include <QAbstractTextDocumentLayout>
18 #include <QHeaderView>
21 #include <QToolButton>
22 #include <QFileDialog>
23 #include <QPlainTextDocumentLayout>
24 #include <QSortFilterProxyModel>
25 #include <QActionGroup>
38 #include "qgsnative.h"
50 #include <QDragEnterEvent>
55 , mModel( browserModel )
59 layout()->setContentsMargins( 0, 0, 0, 0 );
60 qgis::down_cast< QVBoxLayout * >( layout() )->setSpacing( 0 );
62 mBrowserView =
new QgsDockBrowserTreeView(
this );
63 mLayoutBrowser->addWidget( mBrowserView );
65 mWidgetFilter->hide();
66 mLeFilter->setPlaceholderText( tr(
"Type here to filter visible items…" ) );
69 QMenu *menu =
new QMenu(
this );
70 menu->setSeparatorsCollapsible(
false );
71 mBtnFilterOptions->setMenu( menu );
72 QAction *action =
new QAction( tr(
"Case Sensitive" ), menu );
73 action->setData(
"case" );
74 action->setCheckable(
true );
75 action->setChecked(
false );
76 connect( action, &QAction::toggled,
this, &QgsBrowserWidget::setCaseSensitive );
77 menu->addAction( action );
78 QActionGroup *group =
new QActionGroup( menu );
79 action =
new QAction( tr(
"Filter Pattern Syntax" ), group );
80 action->setSeparator(
true );
81 menu->addAction( action );
82 action =
new QAction( tr(
"Normal" ), group );
84 action->setCheckable(
true );
85 action->setChecked(
true );
86 menu->addAction( action );
87 action =
new QAction( tr(
"Wildcard(s)" ), group );
89 action->setCheckable(
true );
90 menu->addAction( action );
91 action =
new QAction( tr(
"Regular Expression" ), group );
93 action->setCheckable(
true );
94 menu->addAction( action );
96 mBrowserView->setExpandsOnDoubleClick(
false );
99 connect( mActionAddLayers, &QAction::triggered,
this, &QgsBrowserWidget::addSelectedLayers );
100 connect( mActionCollapse, &QAction::triggered, mBrowserView, &QgsDockBrowserTreeView::collapseAll );
101 connect( mActionShowFilter, &QAction::triggered,
this, &QgsBrowserWidget::showFilterWidget );
102 connect( mActionPropertiesWidget, &QAction::triggered,
this, &QgsBrowserWidget::propertiesWidgetToggled );
103 connect( mLeFilter, &QgsFilterLineEdit::returnPressed,
this, &QgsBrowserWidget::setFilter );
105 connect( mLeFilter, &QgsFilterLineEdit::textChanged,
this, &QgsBrowserWidget::setFilter );
106 connect( group, &QActionGroup::triggered,
this, &QgsBrowserWidget::setFilterSyntax );
107 connect( mBrowserView, &QgsDockBrowserTreeView::customContextMenuRequested,
this, &QgsBrowserWidget::showContextMenu );
108 connect( mBrowserView, &QgsDockBrowserTreeView::doubleClicked,
this, &QgsBrowserWidget::itemDoubleClicked );
109 connect( mSplitter, &QSplitter::splitterMoved,
this, &QgsBrowserWidget::splitterMoved );
128 mBrowserView->setSettingsSection( objectName().toLower() );
129 mBrowserView->setBrowserModel( mModel );
130 mBrowserView->setModel( mProxyModel );
131 mBrowserView->setSortingEnabled(
true );
132 mBrowserView->sortByColumn( 0, Qt::AscendingOrder );
134 mBrowserView->setTextElideMode( Qt::ElideNone );
135 mBrowserView->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
136 mBrowserView->header()->setStretchLastSection(
false );
139 connect( mBrowserView->selectionModel(), &QItemSelectionModel::selectionChanged,
140 this, &QgsBrowserWidget::selectionChanged );
148 mActionPropertiesWidget->setChecked( settings.
value( settingsSection() +
"/propertiesWidgetEnabled",
false ).toBool() );
149 mPropertiesWidget->setVisible(
false );
151 mSplitter->restoreState( settings.
value( QStringLiteral(
"%1/splitterState" ).arg( settingsSection() ) ).toByteArray() );
154 QWidget::showEvent( e );
157 void QgsBrowserWidget::itemDoubleClicked(
const QModelIndex &index )
168 if ( provider->handleDoubleClick( item, context ) )
176 if ( mBrowserView->isExpanded( index ) )
177 mBrowserView->collapse( index );
179 mBrowserView->expand( index );
183 void QgsBrowserWidget::onOptionsChanged()
185 std::function< void(
const QModelIndex &index ) > updateItem;
186 updateItem = [
this, &updateItem](
const QModelIndex & index )
190 dirItem->reevaluateMonitoring();
193 const int rowCount = mModel->
rowCount( index );
194 for (
int i = 0; i < rowCount; ++i )
196 const QModelIndex child = mModel->
index( i, 0, index );
201 for (
int i = 0; i < mModel->
rowCount(); ++i )
203 updateItem( mModel->
index( i, 0 ) );
207 void QgsBrowserWidget::showContextMenu( QPoint pt )
209 QModelIndex index = mProxyModel->mapToSource( mBrowserView->indexAt( pt ) );
214 const QModelIndexList selection = mBrowserView->selectionModel()->selectedIndexes();
215 QList< QgsDataItem * > selectedItems;
216 selectedItems.reserve( selection.size() );
217 for (
const QModelIndex &selectedIndex : selection )
221 selectedItems << selectedItem;
224 QMenu *menu =
new QMenu(
this );
226 const QList<QMenu *> menus = item->
menus( menu );
227 QList<QAction *> actions = item->
actions( menu );
229 if ( !menus.isEmpty() )
231 for ( QMenu *mn : menus )
237 if ( !actions.isEmpty() )
239 if ( !menu->actions().isEmpty() )
240 menu->addSeparator();
242 menu->addActions( actions );
250 return a->precedenceWhenPopulatingMenus() < b->precedenceWhenPopulatingMenus();
254 provider->populateContextMenu( item, menu, selectedItems, context );
257 if ( menu->actions().isEmpty() )
263 menu->popup( mBrowserView->mapToGlobal( pt ) );
279 mDisabledDataItemsKeys = filter;
289 refreshModel( QModelIndex() );
292 void QgsBrowserWidget::refreshModel(
const QModelIndex &index )
294 if ( mModel && mProxyModel )
311 for (
int i = 0; i < mModel->
rowCount( index ); i++ )
313 QModelIndex idx = mModel->
index( i, 0, index );
314 QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
334 void QgsBrowserWidget::addLayer(
QgsLayerItem *layerItem )
342 void QgsBrowserWidget::addSelectedLayers()
344 QApplication::setOverrideCursor( Qt::WaitCursor );
347 QModelIndexList list = mBrowserView->selectionModel()->selectedIndexes();
348 std::sort( list.begin(), list.end() );
351 const auto constList = list;
352 for (
const QModelIndex &index : constList )
357 QgsProjectItem *projectItem = qobject_cast<QgsProjectItem *>( item );
359 emit
openFile( projectItem->
path(), QStringLiteral(
"project" ) );
361 QApplication::restoreOverrideCursor();
367 for (
int i = list.size() - 1; i >= 0; i-- )
372 QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
374 addLayer( layerItem );
378 QApplication::restoreOverrideCursor();
381 void QgsBrowserWidget::hideItem()
383 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
394 void QgsBrowserWidget::showProperties()
396 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
403 QgsBrowserPropertiesDialog *dialog =
new QgsBrowserPropertiesDialog( settingsSection(),
this );
404 dialog->setAttribute( Qt::WA_DeleteOnClose );
405 dialog->setItem( item, createContext() );
410 void QgsBrowserWidget::showFilterWidget(
bool visible )
412 mWidgetFilter->setVisible( visible );
415 mLeFilter->setText( QString() );
420 mLeFilter->setFocus();
424 void QgsBrowserWidget::setFilter()
426 QString filter = mLeFilter->text();
437 void QgsBrowserWidget::setFilterSyntax( QAction *action )
439 if ( !action || ! mProxyModel )
445 void QgsBrowserWidget::setCaseSensitive(
bool caseSensitive )
452 int QgsBrowserWidget::selectedItemsCount()
454 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
455 if ( selectionModel )
457 return selectionModel->selectedIndexes().size();
469 void QgsBrowserWidget::selectionChanged(
const QItemSelection &selected,
const QItemSelection &deselected )
472 Q_UNUSED( deselected )
473 if ( mActionPropertiesWidget->isChecked() )
475 setPropertiesWidget();
479 void QgsBrowserWidget::clearPropertiesWidget()
481 while ( mPropertiesLayout->count() > 0 )
483 delete mPropertiesLayout->itemAt( 0 )->widget();
485 mPropertiesWidget->setVisible(
false );
488 void QgsBrowserWidget::setPropertiesWidget()
490 clearPropertiesWidget();
491 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
492 if ( selectionModel )
494 QModelIndexList indexes = selectionModel->selectedIndexes();
495 if ( indexes.size() == 1 )
497 QModelIndex index = mProxyModel->mapToSource( indexes.value( 0 ) );
500 QgsBrowserPropertiesWidget *propertiesWidget = QgsBrowserPropertiesWidget::createWidget( item, context, mPropertiesWidget );
501 if ( propertiesWidget )
503 propertiesWidget->setCondensedMode(
true );
504 mPropertiesLayout->addWidget( propertiesWidget );
508 mPropertiesWidget->setVisible( mPropertiesLayout->count() > 0 );
511 void QgsBrowserWidget::enablePropertiesWidget(
bool enable )
513 mActionPropertiesWidget->setChecked( enable );
514 propertiesWidgetToggled( enable );
517 void QgsBrowserWidget::propertiesWidgetToggled(
bool enabled )
519 if ( enabled && selectedItemsCount() == 1 )
521 setPropertiesWidget();
525 clearPropertiesWidget();
529 settings.
setValue( settingsSection() +
"/propertiesWidgetEnabled", enabled );
534 if ( index.isValid() )
536 QModelIndex proxyIndex = mProxyModel->mapFromSource( index );
537 mBrowserView->expand( proxyIndex );
538 mBrowserView->setCurrentIndex( proxyIndex );
542 void QgsBrowserWidget::splitterMoved()
545 settings.
setValue( QStringLiteral(
"%1/splitterState" ).arg( settingsSection() ), mSplitter->saveState() );