68void QQuickSideBar::setDialog(QQuickDialog *dialog)
71 if (dialog == d->dialog)
74 if (
auto fileDialog = qobject_cast<QQuickFileDialogImpl *>(d->dialog))
75 QObjectPrivate::disconnect(fileDialog, &QQuickFileDialogImpl::currentFolderChanged, d,
76 &QQuickSideBarPrivate::folderChanged);
80 if (
auto fileDialog = qobject_cast<QQuickFileDialogImpl *>(d->dialog))
81 QObjectPrivate::connect(fileDialog, &QQuickFileDialogImpl::currentFolderChanged, d,
82 &QQuickSideBarPrivate::folderChanged);
93void QQuickSideBar::setFolderPaths(
const QList<QStandardPaths::StandardLocation> &folderPaths)
96 if (folderPaths == d->folderPaths)
99 const auto oldEffective = effectiveFolderPaths();
101 d->folderPaths = folderPaths;
102 emit folderPathsChanged();
104 if (oldEffective != effectiveFolderPaths())
105 emit effectiveFolderPathsChanged();
202QQuickItem *QQuickSideBarPrivate::createDelegateItem(QQmlComponent *component,
203 const QVariantMap &initialProperties)
208 QQmlContext *context = component->creationContext();
212 context = qmlContext(q);
216 if (!component->isBound() && initialProperties.isEmpty()) {
217 context =
new QQmlContext(context, q);
218 context->setContextObject(q);
221 QQuickItem *item = qobject_cast<QQuickItem *>(
222 component->createWithInitialProperties(initialProperties, context));
224 QQml_setParent_noEvent(item, q);
228void QQuickSideBarPrivate::repopulate()
232 if (repopulating || !buttonDelegate || !separatorDelegate || !addFavoriteDelegate || !q->contentItem())
235 QScopedValueRollback repopulateGuard(repopulating,
true);
237 auto updateIconSourceAndSize = [
this](QQuickAbstractButton *button,
const QUrl &iconUrl) {
241 QQuickIcon icon = button->icon();
242 icon.setSource(iconUrl);
243 const QSize iconSize = dialogIconSize();
244 icon.setWidth(iconSize.width());
245 icon.setHeight(iconSize.height());
246 button->setIcon(icon);
249 auto createButtonDelegate = [
this, q, &updateIconSourceAndSize](
int index,
const QString &folderPath,
const QUrl &iconUrl) {
250 const QString displayName = displayNameFromFolderPath(folderPath);
251 QVariantMap initialProperties = {
252 {
"index"_L1, QVariant::fromValue(index) },
253 {
"folderName"_L1, QVariant::fromValue(displayName) },
256 if (QQuickItem *buttonItem = createDelegateItem(buttonDelegate, initialProperties)) {
257 if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(buttonItem)) {
258 QObjectPrivate::connect(button, &QQuickAbstractButton::clicked,
this,
259 &QQuickSideBarPrivate::buttonClicked);
260 updateIconSourceAndSize(button, iconUrl);
262 insertItem(q->count(), buttonItem);
267 while (q->count() > 0)
268 q->removeItem(q->itemAt(0));
271 const auto folders = q->effectiveFolderPaths();
272 const auto favorites = q->favoritePaths();
273 showSeparator = !folders.isEmpty() && (!favorites.isEmpty() || showAddFavoriteDelegate());
276 for (
auto &folder : folders)
277 createButtonDelegate(insertIndex++, QStandardPaths::displayName(folder), folderIconSource(folder));
280 if (QQuickItem *separatorItem = createDelegateItem(separatorDelegate, {{
"visible"_L1,
false}})) {
281 separatorImplicitSize = separatorItem->implicitHeight();
283 separatorItem->setVisible(
true);
284 insertItem(insertIndex++, separatorItem);
286 separatorItem->deleteLater();
291 const QString labelText = QCoreApplication::translate(
"FileDialog",
"Add Favorite");
292 const QVariantMap initialProperties = {
293 {
"labelText"_L1, QVariant::fromValue(labelText) },
294 {
"dragHovering"_L1, QVariant::fromValue(addFavoriteDelegateHovered()) },
295 {
"visible"_L1,
false}
297 if (
auto *addFavoriteDelegateItem = createDelegateItem(addFavoriteDelegate, initialProperties)) {
298 addFavoriteButtonImplicitSize = addFavoriteDelegateItem->implicitHeight();
299 if (showAddFavoriteDelegate()) {
300 addFavoriteDelegateItem->setVisible(
true);
301 if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(addFavoriteDelegateItem))
302 updateIconSourceAndSize(button, addFavoriteIconUrl());
303 insertItem(insertIndex++, addFavoriteDelegateItem);
305 addFavoriteDelegateItem->deleteLater();
310 for (
auto &favorite : favorites)
311 createButtonDelegate(insertIndex++, favorite.toLocalFile(), folderIconSource());
313 q->setCurrentIndex(-1);
316void QQuickSideBarPrivate::buttonClicked()
319 if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(q->sender())) {
320 const int buttonIndex = contentModel->indexOf(button,
nullptr);
321 q->setCurrentIndex(buttonIndex);
323 currentButtonClickedUrl = QUrl();
325 const int offset = q->effectiveFolderPaths().size() + (showSeparator ? 1 : 0);
326 if (buttonIndex >= offset)
327 currentButtonClickedUrl = q->favoritePaths().at(buttonIndex - offset);
329 currentButtonClickedUrl = QUrl::fromLocalFile(
330 QStandardPaths::writableLocation(q->effectiveFolderPaths().at(buttonIndex)));
332 currentButtonClickedUrl.setScheme(
"file"_L1);
333 setDialogFolder(currentButtonClickedUrl);
376QUrl QQuickSideBarPrivate::folderIconSource(QStandardPaths::StandardLocation stdLocation)
const
378 switch (stdLocation) {
379 case QStandardPaths::DesktopLocation:
380 return QUrl(
"qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/sidebar-desktop.png"_L1);
381 case QStandardPaths::DocumentsLocation:
382 return QUrl(
"qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/sidebar-documents.png"_L1);
383 case QStandardPaths::MusicLocation:
384 return QUrl(
"qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/sidebar-music.png"_L1);
385 case QStandardPaths::MoviesLocation:
386 return QUrl(
"qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/sidebar-video.png"_L1);
387 case QStandardPaths::PicturesLocation:
388 return QUrl(
"qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/sidebar-photo.png"_L1);
389 case QStandardPaths::HomeLocation:
390 return QUrl(
"qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/sidebar-home.png"_L1);
391 case QStandardPaths::DownloadLocation:
392 return QUrl(
"qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/sidebar-downloads.png"_L1);
394 return QUrl(
"qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/sidebar-folder.png"_L1);
505void QQuickSideBarPrivate::handleContextMenuRequested(QPointF pos)
508 const int offset = q->effectiveFolderPaths().size() + (showSeparator ? 1 : 0);
509 for (
int i = offset; i < q->count(); ++i) {
510 QQuickItem *itm = q->itemAt(i);
511 if (itm->contains(itm->mapFromItem(q, pos))) {
512 auto favorites = q->favoritePaths();
513 urlToBeRemoved = favorites.value(i - offset);
515 if (!urlToBeRemoved.isEmpty() && !menu) {
516 QQmlEngine *eng = qmlEngine(q);
518 QQmlContext *context = qmlContext(q);
519 QQmlComponent component(eng);
520 component.loadFromModule(
"QtQuick.Controls",
"Menu");
521 menu = qobject_cast<QQuickMenu*>(component.create(context));
523 auto *removeAction =
new QQuickAction(menu);
524 removeAction->setText(QCoreApplication::translate(
"FileDialog",
"Remove"));
525 menu->addAction(removeAction);
526 connect(removeAction, &QQuickAction::triggered,
this, &QQuickSideBarPrivate::handleRemoveAction);
529 contextMenu->setMenu(menu);
533 contextMenu->setMenu(
nullptr);
559qreal QQuickSideBarPrivate::getContentHeight()
const
561 Q_Q(
const QQuickSideBar);
565 const int modelCount = contentModel->count();
566 const int folderPathCount = q->effectiveFolderPaths().count();
569 QQuickListView *listView = contentItem->findChild<QQuickListView*>();
571 spacing = listView->spacing();
573 qreal totalHeight = 0;
575 for (; i < qMin(modelCount, folderPathCount); ++i) {
576 QQuickItem *item = q->itemAt(i);
578 totalHeight += item->implicitHeight();
583 totalHeight += (i - 1) * spacing;
585 if (!qFuzzyIsNull(separatorImplicitSize))
586 totalHeight += separatorImplicitSize + spacing;
587 if (!qFuzzyIsNull(addFavoriteButtonImplicitSize))
588 totalHeight += addFavoriteButtonImplicitSize + spacing;