18 #include <QAbstractTextDocumentLayout> 19 #include <QHeaderView> 22 #include <QToolButton> 23 #include <QFileDialog> 24 #include <QPlainTextDocumentLayout> 25 #include <QSortFilterProxyModel> 40 #include <QDragEnterEvent> 44 , mModel( browserModel )
45 , mPropertiesWidgetEnabled( false )
46 , mPropertiesWidgetHeight( 0 )
50 mContents->layout()->setContentsMargins( 0, 0, 0, 0 );
51 mContents->layout()->setMargin( 0 );
52 static_cast< QVBoxLayout *
>( mContents->layout() )->setSpacing( 0 );
54 setWindowTitle( name );
56 mBrowserView =
new QgsDockBrowserTreeView(
this );
57 mLayoutBrowser->addWidget( mBrowserView );
59 mWidgetFilter->hide();
60 mLeFilter->setPlaceholderText( tr(
"Type here to filter visible items…" ) );
63 QMenu *menu =
new QMenu(
this );
64 menu->setSeparatorsCollapsible(
false );
65 mBtnFilterOptions->setMenu( menu );
66 QAction *action =
new QAction( tr(
"Case Sensitive" ), menu );
67 action->setData(
"case" );
68 action->setCheckable(
true );
69 action->setChecked(
false );
71 menu->addAction( action );
72 QActionGroup *group =
new QActionGroup( menu );
73 action =
new QAction( tr(
"Filter Pattern Syntax" ), group );
74 action->setSeparator(
true );
75 menu->addAction( action );
76 action =
new QAction( tr(
"Normal" ), group );
77 action->setData(
"normal" );
78 action->setCheckable(
true );
79 action->setChecked(
true );
80 menu->addAction( action );
81 action =
new QAction( tr(
"Wildcard(s)" ), group );
82 action->setData(
"wildcard" );
83 action->setCheckable(
true );
84 menu->addAction( action );
85 action =
new QAction( tr(
"Regular Expression" ), group );
86 action->setData(
"regexp" );
87 action->setCheckable(
true );
88 menu->addAction( action );
92 connect( mActionCollapse, &QAction::triggered, mBrowserView, &QgsDockBrowserTreeView::collapseAll );
100 connect( mBrowserView, &QgsDockBrowserTreeView::doubleClicked,
this, &QgsBrowserDockWidget::itemDoubleClicked );
107 settings.
setValue( settingsSection() +
"/propertiesWidgetEnabled", mPropertiesWidgetEnabled );
109 settings.
setValue( settingsSection() +
"/propertiesWidgetHeight", mPropertiesWidgetHeight );
121 mProxyModel =
new QgsBrowserTreeFilterProxyModel(
this );
122 mProxyModel->setBrowserModel( mModel );
123 mBrowserView->setSettingsSection( objectName().toLower() );
124 mBrowserView->setBrowserModel( mModel );
125 mBrowserView->setModel( mProxyModel );
126 mBrowserView->setSortingEnabled(
true );
127 mBrowserView->sortByColumn( 0, Qt::AscendingOrder );
129 mBrowserView->setTextElideMode( Qt::ElideNone );
130 mBrowserView->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
131 mBrowserView->header()->setStretchLastSection(
false );
134 connect( mBrowserView->selectionModel(), &QItemSelectionModel::selectionChanged,
144 mPropertiesWidgetEnabled = settings.
value( settingsSection() +
"/propertiesWidgetEnabled",
false ).toBool();
145 mActionPropertiesWidget->setChecked( mPropertiesWidgetEnabled );
146 mPropertiesWidget->setVisible(
false );
148 mPropertiesWidgetHeight = settings.
value( settingsSection() +
"/propertiesWidgetHeight" ).toFloat();
149 QList<int> sizes = mSplitter->sizes();
150 int total = sizes.value( 0 ) + sizes.value( 1 );
151 int height = ( int )total * mPropertiesWidgetHeight;
153 sizes << total - height << height;
154 mSplitter->setSizes( sizes );
160 void QgsBrowserDockWidget::itemDoubleClicked(
const QModelIndex &index )
172 void QgsBrowserDockWidget::renameFavorite()
174 QgsDataItem *dataItem = mModel->
dataItem( mProxyModel->mapToSource( mBrowserView->currentIndex() ) );
178 QgsFavoriteItem *favorite = qobject_cast< QgsFavoriteItem * >( dataItem );
182 QgsNewNameDialog dlg( tr(
"favorite “%1”" ).arg( favorite->name() ), favorite->name() );
183 dlg.setWindowTitle( tr(
"Rename Favorite" ) );
184 if ( dlg.exec() != QDialog::Accepted || dlg.name() == favorite->name() )
187 favorite->rename( dlg.name() );
192 QModelIndex index = mProxyModel->mapToSource( mBrowserView->indexAt( pt ) );
197 QMenu *menu =
new QMenu(
this );
204 if ( item->
parent() && !inFavDirs )
207 menu->addAction( tr(
"Add as a Favorite" ),
this, SLOT(
addFavorite() ) );
209 else if ( inFavDirs )
211 QAction *actionRename =
new QAction( tr(
"Rename Favorite…" ),
this );
212 connect( actionRename, &QAction::triggered,
this, &QgsBrowserDockWidget::renameFavorite );
213 menu->addAction( actionRename );
214 menu->addSeparator();
215 menu->addAction( tr(
"Remove Favorite" ),
this, SLOT(
removeFavorite() ) );
216 menu->addSeparator();
218 menu->addAction( tr(
"Properties…" ),
this, SLOT(
showProperties() ) );
219 menu->addAction( tr(
"Hide from Browser" ),
this, SLOT(
hideItem() ) );
220 QAction *action = menu->addAction( tr(
"Fast Scan this Directory" ),
this, SLOT(
toggleFastScan() ) );
221 action->setCheckable(
true );
222 action->setChecked( settings.
value( QStringLiteral(
"qgis/scanItemsFastScanUris" ),
223 QStringList() ).toStringList().contains( item->
path() ) );
227 menu->addAction( tr(
"Add Selected Layer(s) to Canvas" ),
this, SLOT(
addSelectedLayers() ) );
228 menu->addAction( tr(
"Properties…" ),
this, SLOT(
showProperties() ) );
235 const QList<QMenu *> menus = item->
menus( menu );
236 QList<QAction *> actions = item->
actions( menu );
238 if ( !menus.isEmpty() )
240 for ( QMenu *mn : menus )
246 if ( !actions.isEmpty() )
248 if ( !menu->actions().isEmpty() )
249 menu->addSeparator();
251 menu->addActions( actions );
254 if ( menu->actions().isEmpty() )
260 menu->popup( mBrowserView->mapToGlobal( pt ) );
265 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
279 QString directory = QFileDialog::getExistingDirectory(
this, tr(
"Add directory to favorites" ) );
280 if ( !directory.isEmpty() )
293 mModel->
removeFavorite( mProxyModel->mapToSource( mBrowserView->currentIndex() ) );
298 refreshModel( QModelIndex() );
301 void QgsBrowserDockWidget::refreshModel(
const QModelIndex &index )
303 if ( mModel && mProxyModel )
320 for (
int i = 0; i < mModel->
rowCount( index ); i++ )
322 QModelIndex idx = mModel->
index( i, 0, index );
323 QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
328 if ( mBrowserView->isExpanded( proxyIdx ) || mBrowserView->hasExpandedDescendant( proxyIdx ) || ( child && child->
capabilities2() &
QgsDataItem::Fast ) )
343 void QgsBrowserDockWidget::addLayer(
QgsLayerItem *layerItem )
355 QgsDebugMsg( QString(
"rowCount() = %1" ).arg( mModel->
rowCount( mProxyModel->mapToSource( index ) ) ) );
363 QApplication::setOverrideCursor( Qt::WaitCursor );
364 emit
openFile( projectItem->
path(), QStringLiteral(
"project" ) );
365 QApplication::restoreOverrideCursor();
373 QApplication::setOverrideCursor( Qt::WaitCursor );
374 addLayer( layerItem );
375 QApplication::restoreOverrideCursor();
382 QApplication::setOverrideCursor( Qt::WaitCursor );
385 QModelIndexList list = mBrowserView->selectionModel()->selectedIndexes();
386 std::sort( list.begin(), list.end() );
389 Q_FOREACH (
const QModelIndex &index, list )
396 emit
openFile( projectItem->
path(), QStringLiteral(
"project" ) );
398 QApplication::restoreOverrideCursor();
404 for (
int i = list.size() - 1; i >= 0; i-- )
411 addLayer( layerItem );
415 QApplication::restoreOverrideCursor();
420 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
433 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
440 QgsBrowserPropertiesDialog *dialog =
new QgsBrowserPropertiesDialog( settingsSection(),
this );
441 dialog->setItem( item );
448 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
456 QStringList fastScanDirs = settings.
value( QStringLiteral(
"qgis/scanItemsFastScanUris" ),
457 QStringList() ).toStringList();
458 int idx = fastScanDirs.indexOf( item->
path() );
461 fastScanDirs.removeAt( idx );
465 fastScanDirs << item->
path();
467 settings.
setValue( QStringLiteral(
"qgis/scanItemsFastScanUris" ), fastScanDirs );
473 mWidgetFilter->setVisible( visible );
476 mLeFilter->setText( QString() );
481 mLeFilter->setFocus();
487 QString filter = mLeFilter->text();
489 mProxyModel->setFilter( filter );
500 if ( !action || ! mProxyModel )
502 mProxyModel->setFilterSyntax( action->data().toString() );
509 mProxyModel->setCaseSensitive( caseSensitive );
512 int QgsBrowserDockWidget::selectedItemsCount()
514 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
515 if ( selectionModel )
517 return selectionModel->selectedIndexes().size();
524 Q_UNUSED( selected );
525 Q_UNUSED( deselected );
526 if ( mPropertiesWidgetEnabled )
528 setPropertiesWidget();
532 void QgsBrowserDockWidget::clearPropertiesWidget()
534 while ( mPropertiesLayout->count() > 0 )
536 delete mPropertiesLayout->itemAt( 0 )->widget();
538 mPropertiesWidget->setVisible(
false );
541 void QgsBrowserDockWidget::setPropertiesWidget()
543 clearPropertiesWidget();
544 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
545 if ( selectionModel )
547 QModelIndexList indexes = selectionModel->selectedIndexes();
548 if ( indexes.size() == 1 )
550 QModelIndex index = mProxyModel->mapToSource( indexes.value( 0 ) );
552 QgsBrowserPropertiesWidget *propertiesWidget = QgsBrowserPropertiesWidget::createWidget( item, mPropertiesWidget );
553 if ( propertiesWidget )
555 propertiesWidget->setCondensedMode(
true );
556 mPropertiesLayout->addWidget( propertiesWidget );
560 mPropertiesWidget->setVisible( mPropertiesLayout->count() > 0 );
565 mPropertiesWidgetEnabled = enable;
566 if ( enable && selectedItemsCount() == 1 )
568 setPropertiesWidget();
572 clearPropertiesWidget();
578 QList<int> sizes = mSplitter->sizes();
579 float total = sizes.value( 0 ) + sizes.value( 1 );
580 mPropertiesWidgetHeight = total > 0 ? sizes.value( 1 ) / total : 0;
virtual QList< QMenu * > menus(QWidget *parent)
Returns the list of menus available for this item.
void connectionsChanged()
Connections changed in the browser, forwarded to the widget and used to notify the provider dialogs o...
void hidePath(QgsDataItem *item)
Hide the given path in the browser model.
This class is a composition of two QSettings instances:
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
virtual void depopulate()
Remove children recursively and set as not populated. This is used when refreshing collapsed items...
bool initialized() const
Returns true if the model has been initialized.
QgsDataItem * parent() const
Gets item parent.
virtual bool handleDoubleClick()
Called when a user double clicks on the item.
void initialize()
Delayed initialization, needed because the provider registry must be already populated.
QgsDataItem * dataItem(const QModelIndex &idx) const
void removeFavorite(const QModelIndex &index)
Removes a favorite directory from its corresponding model index.
A directory: contains subdirectories and layers.
Base class for all items in the model.
Can create children. Even items without this capability may have children, but cannot create them...
void addFavoriteDirectory(const QString &directory, const QString &name=QString())
Adds a directory to the favorites group.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
QgsMimeDataUtils::Uri mimeUri() const override
Returns mime URI for the data item.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
void cleared()
Emitted when the widget is cleared.
virtual QList< QAction * > actions(QWidget *parent)
Returns the list of actions available for this item.
void refresh(const QString &path)
Refresh item specified by path.
QList< QgsMimeDataUtils::Uri > UriList
Represents a QGIS project.
A model for showing available data sources and other items in a structured tree.
Item that represents a layer that can be opened with one of the providers.
Data item that can be used to represent QGIS projects.
CreateChildren() is fast enough to be run in main thread when refreshing items, most root items (wms...
Represents a favorite item.
virtual Capabilities capabilities2() const