Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickplatformfolderdialog.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#include <QtCore/qloggingcategory.h>
8#include <QtGui/qwindow.h>
9#include <QtQml/qqmlcontext.h>
10#include <QtQml/qqmlcomponent.h>
11#include <QtQml/qqmlinfo.h>
12#include <QtQuick/qquickwindow.h>
13#include <QtQuickTemplates2/private/qquickdialog_p.h>
14#include <QtQuickTemplates2/private/qquickdialog_p_p.h>
15#include <QtQuickTemplates2/private/qquickpopup_p_p.h>
16#include <QtQuickTemplates2/private/qquickpopupanchors_p.h>
17
19
21
22Q_STATIC_LOGGING_CATEGORY(lcQuickPlatformFolderDialog, "qt.quick.dialogs.quickplatformfolderdialog")
23
24/*!
25 \class QQuickPlatformFolderDialog
26 \internal
27
28 An interface that QQuickFolderDialog can use to access the non-native Qt Quick FolderDialog.
29
30 Both this and the native implementations are created in QQuickAbstractDialog::create().
31*/
32QQuickPlatformFolderDialog::QQuickPlatformFolderDialog(QObject *parent)
33{
34 qCDebug(lcQuickPlatformFolderDialog) << "creating non-native Qt Quick FolderDialog with parent" << parent;
35
36 // Set a parent so that we get deleted if we can't be shown for whatever reason.
37 // Our eventual parent should be the window, though.
38 setParent(parent);
39
40 auto qmlContext = ::qmlContext(parent);
41 if (!qmlContext) {
42 qmlWarning(parent) << "No QQmlContext for QQuickPlatformFolderDialog; can't create non-native FolderDialog implementation";
43 return;
44 }
45
46 const auto dialogQmlUrl = QUrl(QStringLiteral("qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/qml/FolderDialog.qml"));
47 QQmlComponent folderDialogComponent(qmlContext->engine(), dialogQmlUrl, parent);
48 if (!folderDialogComponent.isReady()) {
49 qmlWarning(parent) << "Failed to load non-native FolderDialog implementation:\n" << folderDialogComponent.errorString();
50 return;
51 }
52 m_dialog = qobject_cast<QQuickFolderDialogImpl*>(folderDialogComponent.create());
53 if (!m_dialog) {
54 qmlWarning(parent) << "Failed to create an instance of the non-native FolderDialog:\n" << folderDialogComponent.errorString();
55 return;
56 }
57 // Give it a parent until it's parented to the window in show().
58 m_dialog->setParent(this);
59
60 connect(m_dialog, &QQuickDialog::accepted, this, &QPlatformDialogHelper::accept);
61 connect(m_dialog, &QQuickDialog::rejected, this, &QPlatformDialogHelper::reject);
62
63 connect(m_dialog, &QQuickFolderDialogImpl::selectedFolderChanged, this, &QQuickPlatformFolderDialog::currentChanged);
64 connect(m_dialog, &QQuickFolderDialogImpl::currentFolderChanged, this, &QQuickPlatformFolderDialog::directoryEntered);
65 connect(m_dialog, &QQuickFolderDialogImpl::selectedFolderChanged, this, &QQuickPlatformFolderDialog::fileSelected);
66
67 // We would do this in QQuickFolderDialogImpl, but we need to ensure that folderChanged()
68 // is connected to directoryEntered() before setting it to ensure that the QQuickFolderDialog is notified.
69 if (m_dialog->currentFolder().isEmpty())
70 m_dialog->setCurrentFolder(QUrl::fromLocalFile(QDir().absolutePath()));
71}
72
73bool QQuickPlatformFolderDialog::isValid() const
74{
75 return m_dialog;
76}
77
78bool QQuickPlatformFolderDialog::defaultNameFilterDisables() const
79{
80 return false;
81}
82
83void QQuickPlatformFolderDialog::setDirectory(const QUrl &directory)
84{
85 if (!m_dialog)
86 return;
87
88 m_dialog->setCurrentFolder(directory);
89}
90
91QUrl QQuickPlatformFolderDialog::directory() const
92{
93 if (!m_dialog)
94 return {};
95
96 return m_dialog->currentFolder();
97}
98
99void QQuickPlatformFolderDialog::selectFile(const QUrl &file)
100{
101 if (!m_dialog)
102 return;
103
104 m_dialog->setSelectedFolder(file);
105}
106
107QList<QUrl> QQuickPlatformFolderDialog::selectedFiles() const
108{
109 // FolderDialog doesn't support multiple selected folders.
110 return { m_dialog->selectedFolder() };
111}
112
113void QQuickPlatformFolderDialog::setFilter()
114{
115}
116
117void QQuickPlatformFolderDialog::selectNameFilter(const QString &/*filter*/)
118{
119}
120
121QString QQuickPlatformFolderDialog::selectedNameFilter() const
122{
123 return QStringLiteral("*.*");
124}
125
126void QQuickPlatformFolderDialog::exec()
127{
128 qCWarning(lcQuickPlatformFolderDialog) << "exec() is not supported for the Qt Quick FolderDialog fallback";
129}
130
131bool QQuickPlatformFolderDialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
132{
133 qCDebug(lcQuickPlatformFolderDialog) << "show called with flags" << flags <<
134 "modality" << modality << "parent" << parent;
135 if (!m_dialog)
136 return false;
137
138 if (!parent)
139 return false;
140
141 auto quickWindow = qobject_cast<QQuickWindow*>(parent);
142 if (!quickWindow) {
143 qmlInfo(this->parent()) << "Parent window (" << parent << ") of non-native dialog is not a QQuickWindow";
144 return false;
145 }
146 m_dialog->setParent(parent);
147 m_dialog->resetParentItem();
148
149 auto popupPrivate = QQuickPopupPrivate::get(m_dialog);
150 popupPrivate->getAnchors()->setCenterIn(m_dialog->parentItem());
151
152 QSharedPointer<QFileDialogOptions> options = QPlatformFileDialogHelper::options();
153 m_dialog->setTitle(options->windowTitle());
154 m_dialog->setOptions(options);
155 m_dialog->setAcceptLabel(options->isLabelExplicitlySet(QFileDialogOptions::Accept)
156 ? options->labelText(QFileDialogOptions::Accept) : QString());
157 m_dialog->setRejectLabel(options->isLabelExplicitlySet(QFileDialogOptions::Reject)
158 ? options->labelText(QFileDialogOptions::Reject) : QString());
159 m_dialog->setWindowModality(modality);
160 m_dialog->open();
161 return true;
162}
163
164void QQuickPlatformFolderDialog::hide()
165{
166 if (!m_dialog)
167 return;
168
169 m_dialog->close();
170}
171
172QQuickFolderDialogImpl *QQuickPlatformFolderDialog::dialog() const
173{
174 return m_dialog;
175}
176
177QT_END_NAMESPACE
178
179#include "moc_qquickplatformfolderdialog_p.cpp"