Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquickfiledialog.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
5
6#include <QtCore/qlist.h>
7#include <QtCore/qloggingcategory.h>
8#include <QtQml/qqmlfile.h>
9#include <QtQml/qqmlinfo.h>
10
11#include <QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h>
12
14
15using namespace Qt::StringLiterals;
16
18Q_LOGGING_CATEGORY(lcFileDialog, "qt.quick.dialogs.filedialog")
19
20
24
67
79{
80 return m_fileMode;
81}
82
84{
85 qCDebug(lcFileDialog) << "setFileMode called with" << mode;
86 if (mode == m_fileMode)
87 return;
88
89 switch (mode) {
90 case OpenFile:
93 break;
94 case OpenFiles:
97 break;
98 case SaveFile:
101 break;
102 default:
103 break;
104 }
105
106 m_fileMode = mode;
108}
109
128{
129 return addDefaultSuffix(m_selectedFiles.value(0));
130}
131
133{
134 setSelectedFiles({ selectedFile });
135}
136
149{
150 return addDefaultSuffixes(m_selectedFiles);
151}
152
153void QQuickFileDialog::setSelectedFiles(const QList<QUrl> &selectedFiles)
154{
155 qCDebug(lcFileDialog) << "setSelectedFiles called with" << selectedFiles;
156 if (m_selectedFiles == selectedFiles)
157 return;
158
159 if (m_fileMode == SaveFile && selectedFiles.size() > 1) {
160 qmlWarning(this) << "Cannot set more than one selected file when fileMode is SaveFile";
161 return;
162 }
163
164 if (m_fileMode != SaveFile) {
165 for (const auto &selectedFile : selectedFiles) {
166 const QString selectedFilePath = QQmlFile::urlToLocalFileOrQrc(selectedFile);
167 if (!QFileInfo::exists(selectedFilePath)) {
168 qmlWarning(this) << "Cannot set " << selectedFilePath
169 << " as a selected file because it doesn't exist";
170 return;
171 }
172 }
173 }
174
175 const auto newFirstSelectedFile = selectedFiles.value(0);
176 const bool firstChanged = m_selectedFiles.value(0) != newFirstSelectedFile;
177 m_selectedFiles = selectedFiles;
178 m_options->setInitiallySelectedFiles(m_selectedFiles);
179 if (firstChanged) {
182 }
185}
186
196{
197 return selectedFile();
198}
199
201{
202 setSelectedFiles(QList<QUrl>() << file);
203}
204
214{
215 return selectedFiles();
216}
217
218void QQuickFileDialog::setCurrentFiles(const QList<QUrl> &currentFiles)
219{
220 setSelectedFiles(currentFiles);
221}
222
232{
233 if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(handle()))
234 return fileDialog->directory();
235
236 // If we're not using a native file dialog and the folder is invalid,
237 // return the current directory.
238 if (!m_options->initialDirectory().isValid())
240
241 return m_options->initialDirectory();
242}
243
244void QQuickFileDialog::setCurrentFolder(const QUrl &currentFolder)
245{
246 qCDebug(lcFileDialog) << "setCurrentFolder called with" << currentFolder;
247 if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(handle()))
248 fileDialog->setDirectory(currentFolder);
250}
251
270QFileDialogOptions::FileDialogOptions QQuickFileDialog::options() const
271{
272 return m_options->options();
273}
274
275void QQuickFileDialog::setOptions(QFileDialogOptions::FileDialogOptions options)
276{
277 if (options == m_options->options())
278 return;
279
280 m_options->setOptions(options);
282}
283
288
315{
316 return m_options->nameFilters();
317}
318
320{
321 qCDebug(lcFileDialog).nospace() << "setNameFilters called with " << filters
322 << " (old filters were: " << m_options->nameFilters() << ")";
323 if (filters == m_options->nameFilters())
324 return;
325
326 m_options->setNameFilters(filters);
327 if (m_selectedNameFilter) {
328 int index = m_selectedNameFilter->index();
329 if (index < 0 || index >= filters.size())
330 index = 0;
331 m_selectedNameFilter->update(filters.value(index));
332 }
334}
335
340
394{
395 if (!m_selectedNameFilter) {
396 QQuickFileDialog *that = const_cast<QQuickFileDialog *>(this);
397 m_selectedNameFilter = new QQuickFileNameFilter(that);
398 m_selectedNameFilter->setOptions(m_options);
399 }
400 return m_selectedNameFilter;
401}
402
413{
414 return m_options->defaultSuffix();
415}
416
418{
419 if (suffix == m_options->defaultSuffix())
420 return;
421
422 m_options->setDefaultSuffix(suffix);
424}
425
430
448
457
462
479
488
493
495{
497 return false;
498
500 qCDebug(lcDialogs) << " - the FileDialog was told not to use a native dialog; not using native dialog";
501 return false;
502 }
503
504 return true;
505}
506
508{
509 if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(dialog)) {
511 this, [this, fileDialog](){ setSelectedFiles(fileDialog->selectedFiles()); });
513 fileDialog->setOptions(m_options);
514
515 // If the user didn't set an initial selectedFile, ensure that we are synced
516 // with the underlying dialog in case it has set an initially selected file
517 // (as QQuickFileDialogImplPrivate::updateSelectedFile does).
518 if (m_options->initiallySelectedFiles().isEmpty()) {
519 const auto selectedFiles = fileDialog->selectedFiles();
520 if (!selectedFiles.isEmpty())
521 setSelectedFiles(selectedFiles);
522 }
523 }
524}
525
527{
528 m_options->setWindowTitle(title());
529 if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(dialog)) {
530 // Ensure that a name filter is always selected.
531 int index = selectedNameFilter()->index();
532 if (index == -1)
533 index = 0;
534 const QString filter = m_options->nameFilters().value(index);
536
537 fileDialog->setOptions(m_options); // setOptions only assigns a member and isn't virtual
538
540 fileDialog->selectNameFilter(filter);
541
542 // If both selectedFile and currentFolder are set, prefer the former.
543 if (!m_options->initiallySelectedFiles().isEmpty()) {
544 // The user set an initial selectedFile.
545 const QUrl selectedFile = m_options->initiallySelectedFiles().first();
546 fileDialog->selectFile(selectedFile);
547 } else {
548 // The user set an initial currentFolder.
549 const QUrl initialDir = m_options->initialDirectory();
550 // If it's not valid, or it's a file and not a directory, we shouldn't set it.
551 if (m_firstShow && initialDir.isValid() && QDir(QQmlFile::urlToLocalFileOrQrc(initialDir)).exists())
552 fileDialog->setDirectory(m_options->initialDirectory());
553 }
554 }
556}
557
559{
560 if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(dialog)) {
561 if (m_selectedNameFilter)
563 }
564}
565
566QUrl QQuickFileDialog::addDefaultSuffix(const QUrl &file) const
567{
568 QUrl url = file;
569 const QString path = url.path();
570 const QString suffix = m_options->defaultSuffix();
571 // Urls with "content" scheme do not require suffixes. Such schemes are
572 // used on Android.
573 const bool isContentScheme = url.scheme() == u"content"_s;
574 if (!isContentScheme && !suffix.isEmpty() && !path.endsWith(QLatin1Char('/'))
575 && path.lastIndexOf(QLatin1Char('.')) == -1) {
576 url.setPath(path + QLatin1Char('.') + suffix);
577 }
578 return url;
579}
580
582{
583 if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(handle())) {
584 // Take the currently selected files and make them the final set of files.
585 setSelectedFiles(fileDialog->selectedFiles());
586 }
588}
589
590QList<QUrl> QQuickFileDialog::addDefaultSuffixes(const QList<QUrl> &files) const
591{
592 QList<QUrl> urls;
593 urls.reserve(files.size());
594 for (const QUrl &file : files)
595 urls += addDefaultSuffix(file);
596 return urls;
597}
598
600
601#include "moc_qquickfiledialog_p.cpp"
\inmodule QtCore
Definition qdir.h:20
static QString currentPath()
Returns the absolute path of the application's current directory.
Definition qdir.cpp:2054
QList< QUrl > initiallySelectedFiles() const
void setWindowTitle(const QString &)
QString labelText(DialogLabel label) const
void setNameFilters(const QStringList &filters)
void setOptions(FileDialogOptions options)
void setInitiallySelectedNameFilter(const QString &)
QStringList nameFilters() const
FileDialogOptions options() const
void setLabelText(DialogLabel label, const QString &text)
void setFileMode(FileMode mode)
void setAcceptMode(AcceptMode mode)
void setInitialDirectory(const QUrl &)
bool testOption(FileDialogOption option) const
void setDefaultSuffix(const QString &suffix)
void setInitiallySelectedFiles(const QList< QUrl > &)
bool exists() const
Returns true if the file system entry this QFileInfo refers to exists; otherwise returns false.
qsizetype size() const noexcept
Definition qlist.h:397
bool isEmpty() const noexcept
Definition qlist.h:401
T & first()
Definition qlist.h:645
T value(qsizetype i) const
Definition qlist.h:664
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
The QPlatformDialogHelper class allows for platform-specific customization of dialogs.
The QPlatformFileDialogHelper class allows for platform-specific customization of file dialogs.
void currentChanged(const QUrl &path)
void directoryEntered(const QUrl &directory)
void filterSelected(const QString &filter)
static QString urlToLocalFileOrQrc(const QString &)
If url is a local file returns a path suitable for passing to \l{QFile}.
Definition qqmlfile.cpp:742
QPlatformDialogHelper * handle() const
virtual void accept()
\qmlmethod void QtQuick.Dialogs::Dialog::accept()
virtual bool useNativeDialog() const
virtual void onShow(QPlatformDialogHelper *dialog)
void defaultSuffixChanged()
QFileDialogOptions::FileDialogOptions options
void onHide(QPlatformDialogHelper *dialog) override
void onShow(QPlatformDialogHelper *dialog) override
void accept() override
\qmlmethod void QtQuick.Dialogs::Dialog::accept()
void currentFolderChanged()
void setRejectLabel(const QString &label)
void onCreate(QPlatformDialogHelper *dialog) override
void fileModeChanged()
void setOptions(QFileDialogOptions::FileDialogOptions options)
void setDefaultSuffix(const QString &suffix)
bool useNativeDialog() const override
void selectedFilesChanged()
void setCurrentFolder(const QUrl &currentFolder)
void rejectLabelChanged()
void setAcceptLabel(const QString &label)
void nameFiltersChanged()
void setCurrentFile(const QUrl &file)
void setNameFilters(const QStringList &filters)
void setSelectedFile(const QUrl &selectedFile)
void setCurrentFiles(const QList< QUrl > &currentFiles)
void currentFileChanged()
void acceptLabelChanged()
void currentFilesChanged()
void selectedFileChanged()
void setFileMode(FileMode fileMode)
QList< QUrl > selectedFiles
QList< QUrl > currentFiles
QQuickFileNameFilter * selectedNameFilter
void setOptions(const QSharedPointer< QFileDialogOptions > &options)
void update(const QString &filter)
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
\inmodule QtCore
Definition qurl.h:94
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
Definition qurl.cpp:3368
bool isValid() const
Returns true if the URL is non-empty and valid; otherwise returns false.
Definition qurl.cpp:1882
QString scheme() const
Returns the scheme of the URL.
Definition qurl.cpp:1991
void setPath(const QString &path, ParsingMode mode=DecodedMode)
Sets the path of the URL to path.
Definition qurl.cpp:2414
QString path(ComponentFormattingOptions options=FullyDecoded) const
Returns the path of the URL.
Definition qurl.cpp:2468
Combined button and popup list for selecting options.
QStringList m_selectedNameFilter
SharedPointerFileDialogOptions m_options
QList< QString > QStringList
Constructs a string list that contains the given string, str.
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLenum mode
GLuint index
[2]
GLuint GLsizei const GLchar * label
[43]
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLsizei const GLchar *const * path
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
QQuickDialogType
#define emit
QFile file
[0]
QUrl url("example.com")
[constructor-url-reference]
myObject disconnect()
[26]
QFileDialog dialog(this)
[1]
QStringList files
[8]
const QStringList filters({"Image files (*.png *.xpm *.jpg)", "Text files (*.txt)", "Any files (*)" })
[6]
view create()
\inmodule QtCore \reentrant
Definition qchar.h:18