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->addAction( tr(
"Remove Favorite" ),
this, SLOT(
removeFavorite() ) );
215 menu->addSeparator();
217 menu->addAction( tr(
"Properties…" ),
this, SLOT(
showProperties() ) );
218 menu->addAction( tr(
"Hide from Browser" ),
this, SLOT(
hideItem() ) );
219 QAction *action = menu->addAction( tr(
"Fast Scan this Directory" ),
this, SLOT(
toggleFastScan() ) );
220 action->setCheckable(
true );
221 action->setChecked( settings.
value( QStringLiteral(
"qgis/scanItemsFastScanUris" ),
222 QStringList() ).toStringList().contains( item->
path() ) );
226 menu->addAction( tr(
"Add Selected Layer(s) to Canvas" ),
this, SLOT(
addSelectedLayers() ) );
227 menu->addAction( tr(
"Properties…" ),
this, SLOT(
showProperties() ) );
234 const QList<QMenu *> menus = item->
menus( menu );
235 QList<QAction *> actions = item->
actions( menu );
237 if ( !menus.isEmpty() )
239 for ( QMenu *mn : menus )
245 if ( !actions.isEmpty() )
247 if ( !menu->actions().isEmpty() )
248 menu->addSeparator();
250 menu->addActions( actions );
253 if ( menu->actions().isEmpty() )
259 menu->popup( mBrowserView->mapToGlobal( pt ) );
264 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
278 QString directory = QFileDialog::getExistingDirectory(
this, tr(
"Add directory to favorites" ) );
279 if ( !directory.isEmpty() )
292 mModel->
removeFavorite( mProxyModel->mapToSource( mBrowserView->currentIndex() ) );
297 refreshModel( QModelIndex() );
300 void QgsBrowserDockWidget::refreshModel(
const QModelIndex &index )
302 if ( mModel && mProxyModel )
319 for (
int i = 0; i < mModel->
rowCount( index ); i++ )
321 QModelIndex idx = mModel->
index( i, 0, index );
322 QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
327 if ( mBrowserView->isExpanded( proxyIdx ) || mBrowserView->hasExpandedDescendant( proxyIdx ) || ( child && child->
capabilities2() &
QgsDataItem::Fast ) )
342 void QgsBrowserDockWidget::addLayer(
QgsLayerItem *layerItem )
354 QgsDebugMsg( QString(
"rowCount() = %1" ).arg( mModel->
rowCount( mProxyModel->mapToSource( index ) ) ) );
362 QApplication::setOverrideCursor( Qt::WaitCursor );
364 QApplication::restoreOverrideCursor();
372 QApplication::setOverrideCursor( Qt::WaitCursor );
373 addLayer( layerItem );
374 QApplication::restoreOverrideCursor();
381 QApplication::setOverrideCursor( Qt::WaitCursor );
384 QModelIndexList list = mBrowserView->selectionModel()->selectedIndexes();
385 std::sort( list.begin(), list.end() );
388 Q_FOREACH (
const QModelIndex &index, list )
397 QApplication::restoreOverrideCursor();
403 for (
int i = list.size() - 1; i >= 0; i-- )
410 addLayer( layerItem );
414 QApplication::restoreOverrideCursor();
419 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
432 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
439 QgsBrowserPropertiesDialog *dialog =
new QgsBrowserPropertiesDialog( settingsSection(),
this );
440 dialog->setItem( item );
447 QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() );
455 QStringList fastScanDirs = settings.
value( QStringLiteral(
"qgis/scanItemsFastScanUris" ),
456 QStringList() ).toStringList();
457 int idx = fastScanDirs.indexOf( item->
path() );
460 fastScanDirs.removeAt( idx );
464 fastScanDirs << item->
path();
466 settings.
setValue( QStringLiteral(
"qgis/scanItemsFastScanUris" ), fastScanDirs );
472 mWidgetFilter->setVisible( visible );
475 mLeFilter->setText( QString() );
480 mLeFilter->setFocus();
486 QString filter = mLeFilter->text();
488 mProxyModel->setFilter( filter );
499 if ( !action || ! mProxyModel )
501 mProxyModel->setFilterSyntax( action->data().toString() );
508 mProxyModel->setCaseSensitive( caseSensitive );
511 int QgsBrowserDockWidget::selectedItemsCount()
513 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
514 if ( selectionModel )
516 return selectionModel->selectedIndexes().size();
523 Q_UNUSED( selected );
524 Q_UNUSED( deselected );
525 if ( mPropertiesWidgetEnabled )
527 setPropertiesWidget();
531 void QgsBrowserDockWidget::clearPropertiesWidget()
533 while ( mPropertiesLayout->count() > 0 )
535 delete mPropertiesLayout->itemAt( 0 )->widget();
537 mPropertiesWidget->setVisible(
false );
540 void QgsBrowserDockWidget::setPropertiesWidget()
542 clearPropertiesWidget();
543 QItemSelectionModel *selectionModel = mBrowserView->selectionModel();
544 if ( selectionModel )
546 QModelIndexList indexes = selectionModel->selectedIndexes();
547 if ( indexes.size() == 1 )
549 QModelIndex index = mProxyModel->mapToSource( indexes.value( 0 ) );
551 QgsBrowserPropertiesWidget *propertiesWidget = QgsBrowserPropertiesWidget::createWidget( item, mPropertiesWidget );
552 if ( propertiesWidget )
554 propertiesWidget->setCondensedMode(
true );
555 mPropertiesLayout->addWidget( propertiesWidget );
559 mPropertiesWidget->setVisible( mPropertiesLayout->count() > 0 );
564 mPropertiesWidgetEnabled = enable;
565 if ( enable && selectedItemsCount() == 1 )
567 setPropertiesWidget();
571 clearPropertiesWidget();
577 QList<int> sizes = mSplitter->sizes();
578 float total = sizes.value( 0 ) + sizes.value( 1 );
579 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
Provides the number of rows of data exposed by the model.
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.
void setValue(const QString &key, const QVariant &value, const QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
QgsDataItem * parent() const
Get 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.
QgsMimeDataUtils::Uri mimeUri() const override
Return mime URI for the data item.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), const Section section=NoSection) const
Returns the value for setting key.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Returns the index of the item in the model specified by the given row, column and parent index...
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.
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