1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Quick Dialogs module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qquickplatformfiledialog_p.h"
41#include "qquickitem.h"
42
43#include <private/qguiapplication_p.h>
44#include <QWindow>
45#include <QQuickView>
46#include <QQuickWindow>
47
48QT_BEGIN_NAMESPACE
49
50/*!
51 \qmltype FileDialog
52 \instantiates QQuickPlatformFileDialog1
53 \inqmlmodule QtQuick.Dialogs
54 \ingroup qtquickdialogs
55 \brief Dialog component for choosing files from a local filesystem.
56 \since 5.1
57
58 FileDialog provides a basic file chooser: it allows the user to select
59 existing files and/or directories, or create new filenames. The dialog is
60 initially invisible. You need to set the properties as desired first, then
61 set \l visible to true or call \l open().
62
63 Here is a minimal example to open a file dialog and exit after the user
64 chooses a file:
65
66 \qml
67 import QtQuick 2.2
68 import QtQuick.Dialogs 1.0
69
70 FileDialog {
71 id: fileDialog
72 title: "Please choose a file"
73 folder: shortcuts.home
74 onAccepted: {
75 console.log("You chose: " + fileDialog.fileUrls)
76 Qt.quit()
77 }
78 onRejected: {
79 console.log("Canceled")
80 Qt.quit()
81 }
82 Component.onCompleted: visible = true
83 }
84 \endqml
85
86 A FileDialog window is automatically transient for its parent window. So
87 whether you declare the dialog inside an \l Item or inside a \l Window, the
88 dialog will appear centered over the window containing the item, or over
89 the Window that you declared.
90
91 The implementation of FileDialog will be a platform file dialog if
92 possible. If that isn't possible, then it will try to instantiate a
93 \l QFileDialog. If that also isn't possible, then it will fall back to a QML
94 implementation, DefaultFileDialog.qml. In that case you can customize the
95 appearance by editing this file. DefaultFileDialog.qml contains a Rectangle
96 to hold the dialog's contents, because certain embedded systems do not
97 support multiple top-level windows. When the dialog becomes visible, it
98 will automatically be wrapped in a Window if possible, or simply reparented
99 on top of the main window if there can only be one window.
100
101 The QML implementation has a sidebar containing \l shortcuts to common
102 platform-specific locations, and user-modifiable favorites. It uses
103 application-specific \l {Qt.labs.settings}{settings} to store the user's
104 favorites, as well as other user-modifiable state, such as whether or
105 not the sidebar is shown, the positions of the splitters, and the dialog
106 size. The settings are stored in a section called \c QQControlsFileDialog
107 of the application-specific \l QSettings. For example when testing an
108 application with the qml tool, the \c QQControlsFileDialog section will be
109 created in the \c {Qml Runtime} settings file (or registry entry). If an
110 application is started via a custom C++ main() function, it is recommended
111 to set the
112 \l {QCoreApplication::applicationName}{name},
113 \l {QCoreApplication::organizationName}{organization} and
114 \l {QCoreApplication::organizationDomain}{domain} in order to control
115 the location of the application's settings. If you use
116 \l {Qt.labs.settings}{Settings} objects in other parts of an
117 application, they will be stored in other sections of the same file.
118
119 \l QFileDialog stores its settings globally instead of per-application.
120 Platform-native file dialogs may or may not store settings in various
121 platform-dependent ways.
122*/
123
124/*!
125 \qmlsignal QtQuick::Dialogs::FileDialog::accepted
126
127 This signal is emitted when the user has finished using the
128 dialog. You can then inspect the \l fileUrl or \l fileUrls properties to
129 get the selection.
130
131 Example:
132
133 \qml
134 FileDialog {
135 onAccepted: { console.log("Selected file: " + fileUrl) }
136 }
137 \endqml
138
139 The corresponding handler is \c onAccepted.
140*/
141
142/*!
143 \qmlsignal QtQuick::Dialogs::FileDialog::rejected
144
145 This signal is emitted when the user has dismissed the dialog,
146 either by closing the dialog window or by pressing the Cancel button.
147
148 The corresponding handler is \c onRejected.
149*/
150
151/*!
152 \class QQuickPlatformFileDialog1
153 \inmodule QtQuick.Dialogs
154 \internal
155 \since 5.1
156
157 \brief The QQuickPlatformFileDialog1 class provides a file dialog
158
159 The dialog is implemented via the QPlatformFileDialogHelper when possible;
160 otherwise it falls back to a QFileDialog or a QML implementation.
161*/
162
163/*!
164 Constructs a file dialog with parent window \a parent.
165*/
166QQuickPlatformFileDialog1::QQuickPlatformFileDialog1(QObject *parent) :
167 QQuickFileDialog(parent)
168{
169}
170
171/*!
172 Destroys the file dialog.
173*/
174QQuickPlatformFileDialog1::~QQuickPlatformFileDialog1()
175{
176 if (m_dlgHelper)
177 m_dlgHelper->hide();
178 delete m_dlgHelper;
179}
180
181QList<QUrl> QQuickPlatformFileDialog1::fileUrls() const
182{
183 if (m_dialogHelperInUse)
184 return m_dlgHelper->selectedFiles();
185 return QQuickFileDialog::fileUrls();
186}
187
188void QQuickPlatformFileDialog1::setModality(Qt::WindowModality m)
189{
190#ifdef Q_OS_WIN
191 // A non-modal native file dialog is not possible on Windows, so
192 // be stubborn about it. Emit modalityChanged() whether it changed
193 // or not, to ensure that anything which depends on the property
194 // will re-read the actual current value.
195 if (m != Qt::ApplicationModal)
196 m = Qt::ApplicationModal;
197 if (m == m_modality)
198 emit modalityChanged();
199#endif
200 QQuickAbstractFileDialog::setModality(m);
201}
202
203QPlatformFileDialogHelper *QQuickPlatformFileDialog1::helper()
204{
205 QQuickItem *parentItem = qobject_cast<QQuickItem *>(object: parent());
206 if (parentItem)
207 m_parentWindow = parentItem->window();
208
209 if ( !m_dlgHelper && QGuiApplicationPrivate::platformTheme()->
210 usePlatformNativeDialog(type: QPlatformTheme::FileDialog) ) {
211 m_dlgHelper = static_cast<QPlatformFileDialogHelper *>(QGuiApplicationPrivate::platformTheme()
212 ->createPlatformDialogHelper(type: QPlatformTheme::FileDialog));
213 if (!m_dlgHelper)
214 return m_dlgHelper;
215 m_dlgHelper->setOptions(m_options);
216 connect(sender: m_dlgHelper, SIGNAL(filterSelected(QString)), receiver: this, SIGNAL(filterSelected()));
217 connect(sender: m_dlgHelper, SIGNAL(accept()), receiver: this, SLOT(accept()));
218 connect(sender: m_dlgHelper, SIGNAL(reject()), receiver: this, SLOT(reject()));
219 }
220
221 return m_dlgHelper;
222}
223
224void QQuickPlatformFileDialog1::accept()
225{
226 updateFolder(f: folder());
227 QQuickFileDialog::accept();
228}
229
230/*!
231 \qmlproperty bool FileDialog::visible
232
233 This property holds whether the dialog is visible. By default this is
234 false.
235
236 \sa modality
237*/
238
239/*!
240 \qmlproperty Qt::WindowModality FileDialog::modality
241
242 Whether the dialog should be shown modal with respect to the window
243 containing the dialog's parent Item, modal with respect to the whole
244 application, or non-modal.
245
246 By default it is \c Qt.WindowModal.
247
248 Modality does not mean that there are any blocking calls to wait for the
249 dialog to be accepted or rejected; it's only that the user will be
250 prevented from interacting with the parent window and/or the application
251 windows at the same time. You probably need to write an onAccepted handler
252 to actually load or save the chosen file.
253*/
254
255/*!
256 \qmlmethod void FileDialog::open()
257
258 Shows the dialog to the user. It is equivalent to setting \l visible to
259 true.
260*/
261
262/*!
263 \qmlmethod void FileDialog::close()
264
265 Closes the dialog.
266*/
267
268/*!
269 \qmlproperty string FileDialog::title
270
271 The title of the dialog window.
272*/
273
274/*!
275 \qmlproperty bool FileDialog::selectExisting
276
277 Whether only existing files or directories can be selected.
278
279 By default, this property is true. This property must be set to the desired
280 value before opening the dialog. Setting this property to false implies
281 that the dialog is for naming a file to which to save something, or naming
282 a folder to be created; therefore \l selectMultiple must be false.
283*/
284
285/*!
286 \qmlproperty bool FileDialog::selectMultiple
287
288 Whether more than one filename can be selected.
289
290 By default, this property is false. This property must be set to the
291 desired value before opening the dialog. Setting this property to true
292 implies that \l selectExisting must be true.
293*/
294
295/*!
296 \qmlproperty bool FileDialog::selectFolder
297
298 Whether the selected item should be a folder.
299
300 By default, this property is false. This property must be set to the
301 desired value before opening the dialog. Setting this property to true
302 implies that \l selectMultiple must be false and \l selectExisting must be
303 true.
304*/
305
306/*!
307 \qmlproperty url FileDialog::folder
308
309 The path to the currently selected folder. Setting this property before
310 invoking open() will cause the file browser to be initially positioned on
311 the specified folder.
312
313 The value of this property is also updated after the dialog is closed.
314
315 By default, the url is empty.
316
317 \note On iOS, if you set \a folder to \l{shortcuts}
318 {shortcuts.pictures},
319 a native image picker dialog will be used for accessing the user's photo album.
320 The URL returned can be set as \l{Image::source}{source} for \l{Image}.
321 For this to be enabled, the Info.plist assigned to QMAKE_INFO_PLIST in the project file must
322 contain the key, NSPhotoLibraryUsageDescription. See Info.plist documentation from Apple for
323 more information regarding this key. This feature was added in Qt 5.5.
324
325 \sa shortcuts
326*/
327
328/*!
329 \qmlproperty Object FileDialog::shortcuts
330 \since 5.5
331
332 A map of some useful paths from QStandardPaths to their URLs.
333 Each path is verified to exist on the user's computer before being added
334 to this list, at the time when the FileDialog is created.
335
336 \table
337 \row
338 \li \c desktop
339 \li \l QStandardPaths::DesktopLocation
340 \li The user's desktop directory.
341 \row
342 \li \c documents
343 \li \l QStandardPaths::DocumentsLocation
344 \li The directory containing user document files.
345 \row
346 \li \c home
347 \li \l QStandardPaths::HomeLocation
348 \li The user's home directory.
349 \row
350 \li \c music
351 \li \l QStandardPaths::MusicLocation
352 \li The directory containing the user's music or other audio files.
353 \row
354 \li \c movies
355 \li \l QStandardPaths::MoviesLocation
356 \li The directory containing the user's movies and videos.
357 \row
358 \li \c pictures
359 \li \l QStandardPaths::PicturesLocation
360 \li The directory containing the user's pictures or photos. It is always
361 a kind of \c file: URL; but on some platforms, it will be specialized,
362 such that the FileDialog will be realized as a gallery browser dialog.
363 \endtable
364
365 For example, \c shortcuts.home will provide the URL of the user's
366 home directory.
367*/
368
369/*!
370 \qmlproperty list<string> FileDialog::nameFilters
371
372 A list of strings to be used as file name filters. Each string can be a
373 space-separated list of filters; filters may include the ? and * wildcards.
374 The list of filters can also be enclosed in parentheses and a textual
375 description of the filter can be provided.
376
377 For example:
378
379 \qml
380 FileDialog {
381 nameFilters: [ "Image files (*.jpg *.png)", "All files (*)" ]
382 }
383 \endqml
384
385 \note Directories are not excluded by filters.
386 \sa selectedNameFilter
387*/
388
389/*!
390 \qmlproperty string FileDialog::selectedNameFilter
391
392 Which of the \l nameFilters is currently selected.
393
394 This property can be set before the dialog is visible, to set the default
395 name filter, and can also be set while the dialog is visible to set the
396 current name filter. It is also updated when the user selects a different
397 filter.
398*/
399
400/*!
401 \qmlproperty url FileDialog::fileUrl
402
403 The path of the file which was selected by the user.
404
405 \note This property is set only if exactly one file was selected. In all
406 other cases, it will be empty.
407
408 \sa fileUrls
409*/
410
411/*!
412 \qmlproperty list<url> FileDialog::fileUrls
413
414 The list of file paths which were selected by the user.
415*/
416
417/*!
418 \qmlproperty bool FileDialog::sidebarVisible
419 \since 5.4
420
421 This property holds whether the sidebar in the dialog containing shortcuts
422 and bookmarks is visible. By default it depends on the setting stored in
423 the \c QQControlsFileDialog section of the application's
424 \l {Qt.labs.settings}{Settings}.
425*/
426
427/*!
428 \qmlproperty string FileDialog::defaultSuffix
429 \since 5.10
430
431 This property holds the suffix added to the filename if no other suffix was
432 specified.
433
434 This property specifies a string that will be added to the filename if it
435 has no suffix already. The suffix is typically used to indicate the file
436 type (e.g. "txt" indicates a text file).
437
438 If the first character is a dot ('.'), it is removed.
439*/
440
441QT_END_NAMESPACE
442

source code of qtquickcontrols/src/dialogs/qquickplatformfiledialog.cpp