18 #include <QAbstractTextDocumentLayout> 19 #include <QHeaderView> 22 #include <QToolButton> 23 #include <QFileDialog> 24 #include <QPlainTextDocumentLayout> 25 #include <QSortFilterProxyModel> 41 #include <QDragEnterEvent> 45 , mModel( browserModel )
46 , mPropertiesWidgetEnabled( false )
47 , mPropertiesWidgetHeight( 0 )
51 mContents->layout()->setContentsMargins( 0, 0, 0, 0 );
52 mContents->layout()->setMargin( 0 );
53 static_cast< QVBoxLayout *
>( mContents->layout() )->setSpacing( 0 );
55 setWindowTitle( name );
57 mBrowserView =
new QgsDockBrowserTreeView(
this );
58 mLayoutBrowser->addWidget( mBrowserView );
60 mWidgetFilter->hide();
61 mLeFilter->setPlaceholderText( tr(
"Type here to filter visible items…" ) );
64 QMenu *menu =
new QMenu(
this );
65 menu->setSeparatorsCollapsible(
false );
66 mBtnFilterOptions->setMenu( menu );
67 QAction *action =
new QAction( tr(
"Case Sensitive" ), menu );
68 action->setData(
"case" );
69 action->setCheckable(
true );
70 action->setChecked(
false );
72 menu->addAction( action );
73 QActionGroup *group =
new QActionGroup( menu );
74 action =
new QAction( tr(
"Filter Pattern Syntax" ), group );
75 action->setSeparator(
true );
76 menu->addAction( action );
77 action =
new QAction( tr(
"Normal" ), group );
79 action->setCheckable(
true );
80 action->setChecked(
true );
81 menu->addAction( action );
82 action =
new QAction( tr(
"Wildcard(s)" ), group );
84 action->setCheckable(
true );
85 menu->addAction( action );
86 action =
new QAction( tr(
"Regular Expression" ), group );
88 action->setCheckable(
true );
89 menu->addAction( action );
93 connect( mActionCollapse, &QAction::triggered, mBrowserView, &QgsDockBrowserTreeView::collapseAll );
101 connect( mBrowserView, &QgsDockBrowserTreeView::doubleClicked,
this, &QgsBrowserDockWidget::itemDoubleClicked );
108 settings.
setValue( settingsSection() +
"/propertiesWidgetEnabled", mPropertiesWidgetEnabled );
110 settings.
setValue( settingsSection() +
"/propertiesWidgetHeight", mPropertiesWidgetHeight );
124 mBrowserView->setSettingsSection( objectName().toLower() );
125 mBrowserView->setBrowserModel( mModel );
126 mBrowserView->setModel( mProxyModel );
127 mBrowserView->setSortingEnabled(
true );
128 mBrowserView->sortByColumn( 0, Qt::AscendingOrder );
130 mBrowserView->setTextElideMode( Qt::ElideNone );
131 mBrowserView->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
132 mBrowserView->header()->setStretchLastSection(
false );
135 connect( mBrowserView->selectionModel(), &QItemSelectionModel::selectionChanged,
145 mPropertiesWidgetEnabled = settings.
value( settingsSection() +
"/propertiesWidgetEnabled",
false ).toBool();
146 mActionPropertiesWidget->setChecked( mPropertiesWidgetEnabled );
147 mPropertiesWidget->setVisible(
false );
149 mPropertiesWidgetHeight = settings.
value( settingsSection() +
"/propertiesWidgetHeight" ).toFloat();
150 QList<int> sizes = mSplitter->sizes();
151 int total = sizes.value( 0 ) + sizes.value( 1 );
152 int height =
static_cast<int>( total ) * mPropertiesWidgetHeight;
154 sizes << total - height << height;
155 mSplitter->setSizes( sizes );
161 void QgsBrowserDockWidget::itemDoubleClicked(
const QModelIndex &index )
173 void QgsBrowserDockWidget::renameFavorite()
175 QgsDataItem *dataItem = mModel->
dataItem( mProxyModel->mapToSource( mBrowserView->currentIndex() ) );
179 QgsFavoriteItem *favorite = qobject_cast< QgsFavoriteItem * >( dataItem );
183 QgsNewNameDialog dlg( tr(
"favorite “%1”" ).arg( favorite->name() ), favorite->name() );
184 dlg.setWindowTitle( tr(
"Rename Favorite" ) );
185 if ( dlg.exec() != QDialog::Accepted || dlg.name() == favorite->name() )
188 favorite->rename( dlg.name() );
193 QModelIndex index = mProxyModel->mapToSource( mBrowserView->indexAt( pt ) );
198 QMenu *menu =
new QMenu(
this );
205 if ( item->
parent() && !inFavDirs )
208 QAction *addAsFavorite =
new QAction( tr(
"Add as a Favorite" ),
this );
210 menu->addAction( addAsFavorite );
213 else if ( inFavDirs )
215 QAction *actionRename =
new QAction( tr(
"Rename Favorite…" ),
this );
216 connect( actionRename, &QAction::triggered,
this, &QgsBrowserDockWidget::renameFavorite );
217 menu->addAction( actionRename );
218 menu->addSeparator();
219 menu->addAction( tr(
"Remove Favorite" ),
this, SLOT(
removeFavorite() ) );
220 menu->addSeparator();
222 menu->addAction( tr(
"Properties…" ),
this, SLOT(
showProperties() ) );
223 menu->addAction( tr(
"Hide from Browser" ),
this, SLOT(
hideItem() ) );
224 QAction *action = menu->addAction( tr(
"Fast Scan this Directory" ),
this, SLOT(
toggleFastScan() ) );
225 action->setCheckable(
true );
226 action->setChecked( settings.
value( QStringLiteral(
"qgis/scanItemsFastScanUris" ),
227 QStringList() ).toStringList().contains( item->
path() ) );
231 menu->addAction( tr(
"Add Selected Layer(s) to Canvas" ),
this, SLOT(
addSelectedLayers() ) );
232 menu->addAction( tr(
"Properties…" ),
this, SLOT(
showProperties() ) );
239 const QList<QMenu *> menus = item->
menus( menu );
240 QList<QAction *> actions = item->
actions( menu );
242 if ( !menus.isEmpty() )
244 for ( QMenu *mn : menus )
250 if ( !actions.isEmpty() )
252 if ( !menu->actions().isEmpty() )
253 menu->addSeparator();
255 menu->addActions( actions );
258 if ( menu->actions().isEmpty() )
264 menu->popup( mBrowserView->mapToGlobal( pt ) );
269 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
283 QString directory = QFileDialog::getExistingDirectory(
this, tr(
"Add directory to favorites" ) );
284 if ( !directory.isEmpty() )
297 mModel->
removeFavorite( mProxyModel->mapToSource( mBrowserView->currentIndex() ) );
302 refreshModel( QModelIndex() );
305 void QgsBrowserDockWidget::refreshModel(
const QModelIndex &index )
307 if ( mModel && mProxyModel )
324 for (
int i = 0; i < mModel->
rowCount( index ); i++ )
326 QModelIndex idx = mModel->
index( i, 0, index );
327 QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
332 if ( mBrowserView->isExpanded( proxyIdx ) || mBrowserView->hasExpandedDescendant( proxyIdx ) || ( child && child->
capabilities2() &
QgsDataItem::Fast ) )
347 void QgsBrowserDockWidget::addLayer(
QgsLayerItem *layerItem )
359 QgsDebugMsg( QStringLiteral(
"rowCount() = %1" ).arg( mModel->
rowCount( mProxyModel->mapToSource( index ) ) ) );
367 QApplication::setOverrideCursor( Qt::WaitCursor );
368 emit
openFile( projectItem->
path(), QStringLiteral(
"project" ) );
369 QApplication::restoreOverrideCursor();
377 QApplication::setOverrideCursor( Qt::WaitCursor );
378 addLayer( layerItem );
379 QApplication::restoreOverrideCursor();
386 QApplication::setOverrideCursor( Qt::WaitCursor );
389 QModelIndexList list = mBrowserView->selectionModel()->selectedIndexes();
390 std::sort( list.begin(), list.end() );
393 Q_FOREACH (
const QModelIndex &index, list )
400 emit
openFile( projectItem->
path(), QStringLiteral(
"project" ) );
402 QApplication::restoreOverrideCursor();
408 for (
int i = list.size() - 1; i >= 0; i-- )
415 addLayer( layerItem );
419 QApplication::restoreOverrideCursor();
424 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
437 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
444 QgsBrowserPropertiesDialog *dialog =
new QgsBrowserPropertiesDialog( settingsSection(),
this );
445 dialog->setAttribute( Qt::WA_DeleteOnClose );
446 dialog->setItem( item );
453 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
461 QStringList fastScanDirs = settings.
value( QStringLiteral(
"qgis/scanItemsFastScanUris" ),
462 QStringList() ).toStringList();
463 int idx = fastScanDirs.indexOf( item->
path() );
466 fastScanDirs.removeAt( idx );
470 fastScanDirs << item->
path();
472 settings.
setValue( QStringLiteral(
"qgis/scanItemsFastScanUris" ), fastScanDirs );
478 mWidgetFilter->setVisible( visible );
481 mLeFilter->setText( QString() );
486 mLeFilter->setFocus();
492 QString filter = mLeFilter->text();
505 if ( !action || ! mProxyModel )
508 mProxyModel->
setFilterSyntax( static_cast< QgsBrowserProxyModel::FilterSyntax >( action->data().toInt() ) );
518 int QgsBrowserDockWidget::selectedItemsCount()
520 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
521 if ( selectionModel )
523 return selectionModel->selectedIndexes().size();
530 Q_UNUSED( selected );
531 Q_UNUSED( deselected );
532 if ( mPropertiesWidgetEnabled )
534 setPropertiesWidget();
538 void QgsBrowserDockWidget::clearPropertiesWidget()
540 while ( mPropertiesLayout->count() > 0 )
542 delete mPropertiesLayout->itemAt( 0 )->widget();
544 mPropertiesWidget->setVisible(
false );
547 void QgsBrowserDockWidget::setPropertiesWidget()
549 clearPropertiesWidget();
550 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
551 if ( selectionModel )
553 QModelIndexList indexes = selectionModel->selectedIndexes();
554 if ( indexes.size() == 1 )
556 QModelIndex index = mProxyModel->mapToSource( indexes.value( 0 ) );
558 QgsBrowserPropertiesWidget *propertiesWidget = QgsBrowserPropertiesWidget::createWidget( item, mPropertiesWidget );
559 if ( propertiesWidget )
561 propertiesWidget->setCondensedMode(
true );
562 mPropertiesLayout->addWidget( propertiesWidget );
566 mPropertiesWidget->setVisible( mPropertiesLayout->count() > 0 );
571 mPropertiesWidgetEnabled = enable;
572 if ( enable && selectedItemsCount() == 1 )
574 setPropertiesWidget();
578 clearPropertiesWidget();
584 QList<int> sizes = mSplitter->sizes();
585 float total = sizes.value( 0 ) + sizes.value( 1 );
586 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.
virtual Capabilities capabilities2() const
Returns the capabilities for the data item.
This class is a composition of two QSettings instances:
QgsDataItem * parent() const
Gets item parent.
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.
void setBrowserModel(QgsBrowserModel *model)
Sets the underlying browser model.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
virtual void depopulate()
Remove children recursively and set as not populated. This is used when refreshing collapsed items...
void setFilterSyntax(FilterSyntax syntax)
Sets the filter syntax.
#define QgsDebugMsgLevel(str, level)
QgsDataItem * dataItem(const QModelIndex &idx) const
Returns the data item at the specified index, or a nullptr if no item exists at the index...
Regular expression filtering.
virtual bool handleDoubleClick()
Called when a user double clicks on the item.
void setFilterString(const QString &filter)
Sets the filter string to use when filtering items in the model.
void initialize()
Delayed initialization, needed because the provider registry must be already populated.
void removeFavorite(const QModelIndex &index)
Removes a favorite directory from its corresponding model index.
void setFilterCaseSensitivity(Qt::CaseSensitivity sensitivity)
Sets whether item filtering should be case sensitive.
A directory: contains subdirectories and layers.
Base class for all items in the model.
bool initialized() const
Returns true if the model has been initialized.
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.
Standard string filtering.
A QSortFilterProxyModel subclass for filtering and sorting browser model items.
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.