1// Copyright (C) 2017 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
4#include "qquicklabsplatformfolderdialog_p.h"
5
6QT_BEGIN_NAMESPACE
7
8/*!
9 \qmltype FolderDialog
10 \inherits Dialog
11//! \instantiates QQuickLabsPlatformFolderDialog
12 \inqmlmodule Qt.labs.platform
13 \since 5.8
14 \brief A native folder dialog.
15
16 The FolderDialog type provides a QML API for native platform folder dialogs.
17
18 \image qtlabsplatform-folderdialog-gtk.png
19
20 To show a folder dialog, construct an instance of FolderDialog, set the
21 desired properties, and call \l {Dialog::}{open()}. The \l currentFolder
22 property can be used to determine the currently selected folder in the
23 dialog. The \l folder property is updated only after the final selection
24 has been made by accepting the dialog.
25
26 \code
27 MenuItem {
28 text: "Open..."
29 onTriggered: folderDialog.open()
30 }
31
32 FolderDialog {
33 id: folderDialog
34 currentFolder: viewer.folder
35 folder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]
36 }
37
38 MyViewer {
39 id: viewer
40 folder: folderDialog.folder
41 }
42 \endcode
43
44 \section2 Availability
45
46 A native platform folder dialog is currently available on the following platforms:
47
48 \list
49 \li Android
50 \li iOS
51 \li Linux (when running with the GTK+ platform theme)
52 \li macOS
53 \li Windows
54 \endlist
55
56 \input includes/widgets.qdocinc 1
57
58 \labs
59
60 \sa FileDialog, StandardPaths
61*/
62
63QQuickLabsPlatformFolderDialog::QQuickLabsPlatformFolderDialog(QObject *parent)
64 : QQuickLabsPlatformDialog(QPlatformTheme::FileDialog, parent),
65 m_options(QFileDialogOptions::create())
66{
67 m_options->setFileMode(QFileDialogOptions::Directory);
68 m_options->setAcceptMode(QFileDialogOptions::AcceptOpen);
69}
70
71/*!
72 \qmlproperty url Qt.labs.platform::FolderDialog::folder
73
74 This property holds the final accepted folder.
75
76 Unlike the \l currentFolder property, the \c folder property is not updated
77 while the user is selecting folders in the dialog, but only after the final
78 selection has been made. That is, when the user has clicked \uicontrol OK
79 to accept a folder. Alternatively, the \l {Dialog::}{accepted()} signal
80 can be handled to get the final selection.
81
82 \sa currentFolder, {Dialog::}{accepted()}
83*/
84QUrl QQuickLabsPlatformFolderDialog::folder() const
85{
86 return m_folder;
87}
88
89void QQuickLabsPlatformFolderDialog::setFolder(const QUrl &folder)
90{
91 if (m_folder == folder)
92 return;
93
94 m_folder = folder;
95 emit folderChanged();
96}
97
98/*!
99 \qmlproperty url Qt.labs.platform::FolderDialog::currentFolder
100
101 This property holds the currently selected folder in the dialog.
102
103 Unlike the \l folder property, the \c currentFolder property is updated
104 while the user is selecting folders in the dialog, even before the final
105 selection has been made.
106
107 \sa folder
108*/
109QUrl QQuickLabsPlatformFolderDialog::currentFolder() const
110{
111 if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(object: handle())) {
112 const QList<QUrl> selectedFiles = fileDialog->selectedFiles();
113 if (!selectedFiles.isEmpty())
114 return selectedFiles.first();
115 return fileDialog->directory();
116 }
117 return m_options->initialDirectory();
118}
119
120void QQuickLabsPlatformFolderDialog::setCurrentFolder(const QUrl &folder)
121{
122 if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(object: handle()))
123 fileDialog->setDirectory(folder);
124 m_options->setInitialDirectory(folder);
125}
126
127/*!
128 \qmlproperty flags Qt.labs.platform::FolderDialog::options
129
130 This property holds the various options that affect the look and feel of the dialog.
131
132 By default, all options are disabled.
133
134 Options should be set before showing the dialog. Setting them while the dialog is
135 visible is not guaranteed to have an immediate effect on the dialog (depending on
136 the option and on the platform).
137
138 Available options:
139 \value FolderDialog.ShowDirsOnly Only show directories in the folder dialog. By default both folders and directories are shown.
140 \value FolderDialog.DontResolveSymlinks Don't resolve symlinks in the folder dialog. By default symlinks are resolved.
141 \value FolderDialog.ReadOnly Indicates that the dialog doesn't allow creating directories.
142*/
143QFileDialogOptions::FileDialogOptions QQuickLabsPlatformFolderDialog::options() const
144{
145 return m_options->options();
146}
147
148void QQuickLabsPlatformFolderDialog::setOptions(QFileDialogOptions::FileDialogOptions options)
149{
150 if (options == m_options->options())
151 return;
152
153 m_options->setOptions(options);
154 emit optionsChanged();
155}
156
157void QQuickLabsPlatformFolderDialog::resetOptions()
158{
159 setOptions({});
160}
161
162/*!
163 \qmlproperty string Qt.labs.platform::FolderDialog::acceptLabel
164
165 This property holds the label text shown on the button that accepts the dialog.
166
167 When set to an empty string, the default label of the underlying platform is used.
168 The default label is typically \uicontrol Open.
169
170 The default value is an empty string.
171
172 \sa rejectLabel
173*/
174QString QQuickLabsPlatformFolderDialog::acceptLabel() const
175{
176 return m_options->labelText(label: QFileDialogOptions::Accept);
177}
178
179void QQuickLabsPlatformFolderDialog::setAcceptLabel(const QString &label)
180{
181 if (label == m_options->labelText(label: QFileDialogOptions::Accept))
182 return;
183
184 m_options->setLabelText(label: QFileDialogOptions::Accept, text: label);
185 emit acceptLabelChanged();
186}
187
188void QQuickLabsPlatformFolderDialog::resetAcceptLabel()
189{
190 setAcceptLabel(QString());
191}
192
193/*!
194 \qmlproperty string Qt.labs.platform::FolderDialog::rejectLabel
195
196 This property holds the label text shown on the button that rejects the dialog.
197
198 When set to an empty string, the default label of the underlying platform is used.
199 The default label is typically \uicontrol Cancel.
200
201 The default value is an empty string.
202
203 \sa acceptLabel
204*/
205QString QQuickLabsPlatformFolderDialog::rejectLabel() const
206{
207 return m_options->labelText(label: QFileDialogOptions::Reject);
208}
209
210void QQuickLabsPlatformFolderDialog::setRejectLabel(const QString &label)
211{
212 if (label == m_options->labelText(label: QFileDialogOptions::Reject))
213 return;
214
215 m_options->setLabelText(label: QFileDialogOptions::Reject, text: label);
216 emit rejectLabelChanged();
217}
218
219void QQuickLabsPlatformFolderDialog::resetRejectLabel()
220{
221 setRejectLabel(QString());
222}
223
224bool QQuickLabsPlatformFolderDialog::useNativeDialog() const
225{
226 return QQuickLabsPlatformDialog::useNativeDialog()
227 && !m_options->testOption(option: QFileDialogOptions::DontUseNativeDialog);
228}
229
230void QQuickLabsPlatformFolderDialog::onCreate(QPlatformDialogHelper *dialog)
231{
232 if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(object: dialog)) {
233 connect(sender: fileDialog, signal: &QPlatformFileDialogHelper::currentChanged, context: this, slot: &QQuickLabsPlatformFolderDialog::currentFolderChanged);
234 fileDialog->setOptions(m_options);
235 }
236}
237
238void QQuickLabsPlatformFolderDialog::onShow(QPlatformDialogHelper *dialog)
239{
240 m_options->setWindowTitle(title());
241 if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(object: dialog))
242 fileDialog->setOptions(m_options);
243}
244
245void QQuickLabsPlatformFolderDialog::accept()
246{
247 setFolder(currentFolder());
248 QQuickLabsPlatformDialog::accept();
249}
250
251QT_END_NAMESPACE
252
253#include "moc_qquicklabsplatformfolderdialog_p.cpp"
254

source code of qtdeclarative/src/labs/platform/qquicklabsplatformfolderdialog.cpp