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 "qquicklabsplatformfiledialog_p.h" |
5 | |
6 | #include <QtCore/qlist.h> |
7 | |
8 | QT_BEGIN_NAMESPACE |
9 | |
10 | using namespace Qt::StringLiterals; |
11 | |
12 | /*! |
13 | \qmltype FileDialog |
14 | \inherits Dialog |
15 | //! \instantiates QQuickLabsPlatformFileDialog |
16 | \inqmlmodule Qt.labs.platform |
17 | \since 5.8 |
18 | \brief A native file dialog. |
19 | |
20 | The FileDialog type provides a QML API for native platform file dialogs. |
21 | |
22 | \image qtlabsplatform-filedialog-gtk.png |
23 | |
24 | To show a file dialog, construct an instance of FileDialog, set the |
25 | desired properties, and call \l {Dialog::}{open()}. The \l currentFile |
26 | or \l currentFiles properties can be used to determine the currently |
27 | selected file(s) in the dialog. The \l file and \l files properties |
28 | are updated only after the final selection has been made by accepting |
29 | the dialog. |
30 | |
31 | \code |
32 | MenuItem { |
33 | text: "Open..." |
34 | onTriggered: fileDialog.open() |
35 | } |
36 | |
37 | FileDialog { |
38 | id: fileDialog |
39 | currentFile: document.source |
40 | folder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) |
41 | } |
42 | |
43 | MyDocument { |
44 | id: document |
45 | source: fileDialog.file |
46 | } |
47 | \endcode |
48 | |
49 | \section2 Availability |
50 | |
51 | A native platform file dialog is currently available on the following platforms: |
52 | |
53 | \list |
54 | \li Android |
55 | \li iOS |
56 | \li Linux (when running with the GTK+ platform theme) |
57 | \li macOS |
58 | \li Windows |
59 | \endlist |
60 | |
61 | \input includes/widgets.qdocinc 1 |
62 | |
63 | \labs |
64 | |
65 | \sa FolderDialog, StandardPaths |
66 | */ |
67 | |
68 | QQuickLabsPlatformFileDialog::QQuickLabsPlatformFileDialog(QObject *parent) |
69 | : QQuickLabsPlatformDialog(QPlatformTheme::FileDialog, parent), |
70 | m_fileMode(OpenFile), |
71 | m_options(QFileDialogOptions::create()), |
72 | m_selectedNameFilter(nullptr) |
73 | { |
74 | m_options->setFileMode(QFileDialogOptions::ExistingFile); |
75 | m_options->setAcceptMode(QFileDialogOptions::AcceptOpen); |
76 | } |
77 | |
78 | /*! |
79 | \qmlproperty enumeration Qt.labs.platform::FileDialog::fileMode |
80 | |
81 | This property holds the mode of the dialog. |
82 | |
83 | Available values: |
84 | \value FileDialog.OpenFile The dialog is used to select an existing file (default). |
85 | \value FileDialog.OpenFiles The dialog is used to select multiple existing files. |
86 | \value FileDialog.SaveFile The dialog is used to select any file. The file does not have to exist. |
87 | */ |
88 | QQuickLabsPlatformFileDialog::FileMode QQuickLabsPlatformFileDialog::fileMode() const |
89 | { |
90 | return m_fileMode; |
91 | } |
92 | |
93 | void QQuickLabsPlatformFileDialog::setFileMode(FileMode mode) |
94 | { |
95 | if (mode == m_fileMode) |
96 | return; |
97 | |
98 | switch (mode) { |
99 | case OpenFile: |
100 | m_options->setFileMode(QFileDialogOptions::ExistingFile); |
101 | m_options->setAcceptMode(QFileDialogOptions::AcceptOpen); |
102 | break; |
103 | case OpenFiles: |
104 | m_options->setFileMode(QFileDialogOptions::ExistingFiles); |
105 | m_options->setAcceptMode(QFileDialogOptions::AcceptOpen); |
106 | break; |
107 | case SaveFile: |
108 | m_options->setFileMode(QFileDialogOptions::AnyFile); |
109 | m_options->setAcceptMode(QFileDialogOptions::AcceptSave); |
110 | break; |
111 | default: |
112 | break; |
113 | } |
114 | |
115 | m_fileMode = mode; |
116 | emit fileModeChanged(); |
117 | } |
118 | |
119 | /*! |
120 | \qmlproperty url Qt.labs.platform::FileDialog::file |
121 | |
122 | This property holds the final accepted file. |
123 | |
124 | Unlike the \l currentFile property, the \c file property is not updated |
125 | while the user is selecting files in the dialog, but only after the final |
126 | selection has been made. That is, when the user has clicked \uicontrol OK |
127 | to accept a file. Alternatively, the \l {Dialog::}{accepted()} signal |
128 | can be handled to get the final selection. |
129 | |
130 | \sa currentFile, {Dialog::}{accepted()} |
131 | */ |
132 | QUrl QQuickLabsPlatformFileDialog::file() const |
133 | { |
134 | return addDefaultSuffix(file: m_files.value(i: 0)); |
135 | } |
136 | |
137 | void QQuickLabsPlatformFileDialog::setFile(const QUrl &file) |
138 | { |
139 | setFiles(QList<QUrl>() << file); |
140 | } |
141 | |
142 | /*! |
143 | \qmlproperty list<url> Qt.labs.platform::FileDialog::files |
144 | |
145 | This property holds the final accepted files. |
146 | |
147 | Unlike the \l currentFiles property, the \c files property is not updated |
148 | while the user is selecting files in the dialog, but only after the final |
149 | selection has been made. That is, when the user has clicked \uicontrol OK |
150 | to accept files. Alternatively, the \l {Dialog::}{accepted()} signal |
151 | can be handled to get the final selection. |
152 | |
153 | \sa currentFiles, {Dialog::}{accepted()} |
154 | */ |
155 | QList<QUrl> QQuickLabsPlatformFileDialog::files() const |
156 | { |
157 | return addDefaultSuffixes(files: m_files); |
158 | } |
159 | |
160 | void QQuickLabsPlatformFileDialog::setFiles(const QList<QUrl> &files) |
161 | { |
162 | if (m_files == files) |
163 | return; |
164 | |
165 | bool firstChanged = m_files.value(i: 0) != files.value(i: 0); |
166 | m_files = files; |
167 | if (firstChanged) |
168 | emit fileChanged(); |
169 | emit filesChanged(); |
170 | } |
171 | |
172 | /*! |
173 | \qmlproperty url Qt.labs.platform::FileDialog::currentFile |
174 | |
175 | This property holds the currently selected file in the dialog. |
176 | |
177 | Unlike the \l file property, the \c currentFile property is updated |
178 | while the user is selecting files in the dialog, even before the final |
179 | selection has been made. |
180 | |
181 | \sa file, currentFiles |
182 | */ |
183 | QUrl QQuickLabsPlatformFileDialog::currentFile() const |
184 | { |
185 | return currentFiles().value(i: 0); |
186 | } |
187 | |
188 | void QQuickLabsPlatformFileDialog::setCurrentFile(const QUrl &file) |
189 | { |
190 | setCurrentFiles(QList<QUrl>() << file); |
191 | } |
192 | |
193 | /*! |
194 | \qmlproperty list<url> Qt.labs.platform::FileDialog::currentFiles |
195 | |
196 | This property holds the currently selected files in the dialog. |
197 | |
198 | Unlike the \l files property, the \c currentFiles property is updated |
199 | while the user is selecting files in the dialog, even before the final |
200 | selection has been made. |
201 | |
202 | \sa files, currentFile |
203 | */ |
204 | QList<QUrl> QQuickLabsPlatformFileDialog::currentFiles() const |
205 | { |
206 | if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(object: handle())) |
207 | return fileDialog->selectedFiles(); |
208 | return m_options->initiallySelectedFiles(); |
209 | } |
210 | |
211 | void QQuickLabsPlatformFileDialog::setCurrentFiles(const QList<QUrl> &files) |
212 | { |
213 | if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(object: handle())) { |
214 | for (const QUrl &file : files) |
215 | fileDialog->selectFile(filename: file); |
216 | } |
217 | m_options->setInitiallySelectedFiles(files); |
218 | } |
219 | |
220 | /*! |
221 | \qmlproperty url Qt.labs.platform::FileDialog::folder |
222 | |
223 | This property holds the folder where files are selected. |
224 | For selecting a folder, use FolderDialog instead. |
225 | |
226 | \sa FolderDialog |
227 | */ |
228 | QUrl QQuickLabsPlatformFileDialog::folder() const |
229 | { |
230 | if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(object: handle())) |
231 | return fileDialog->directory(); |
232 | return m_options->initialDirectory(); |
233 | } |
234 | |
235 | void QQuickLabsPlatformFileDialog::setFolder(const QUrl &folder) |
236 | { |
237 | if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(object: handle())) |
238 | fileDialog->setDirectory(folder); |
239 | m_options->setInitialDirectory(folder); |
240 | } |
241 | |
242 | /*! |
243 | \qmlproperty flags Qt.labs.platform::FileDialog::options |
244 | |
245 | This property holds the various options that affect the look and feel of the dialog. |
246 | |
247 | By default, all options are disabled. |
248 | |
249 | Options should be set before showing the dialog. Setting them while the dialog is |
250 | visible is not guaranteed to have an immediate effect on the dialog (depending on |
251 | the option and on the platform). |
252 | |
253 | Available options: |
254 | \value FileDialog.DontResolveSymlinks Don't resolve symlinks in the file dialog. By default symlinks are resolved. |
255 | \value FileDialog.DontConfirmOverwrite Don't ask for confirmation if an existing file is selected. By default confirmation is requested. |
256 | \value FileDialog.ReadOnly Indicates that the dialog doesn't allow creating directories. |
257 | \value FileDialog.HideNameFilterDetails Indicates if the file name filter details are hidden or not. |
258 | */ |
259 | QFileDialogOptions::FileDialogOptions QQuickLabsPlatformFileDialog::options() const |
260 | { |
261 | return m_options->options(); |
262 | } |
263 | |
264 | void QQuickLabsPlatformFileDialog::setOptions(QFileDialogOptions::FileDialogOptions options) |
265 | { |
266 | if (options == m_options->options()) |
267 | return; |
268 | |
269 | m_options->setOptions(options); |
270 | emit optionsChanged(); |
271 | } |
272 | |
273 | void QQuickLabsPlatformFileDialog::resetOptions() |
274 | { |
275 | setOptions({}); |
276 | } |
277 | |
278 | /*! |
279 | \qmlproperty list<string> Qt.labs.platform::FileDialog::nameFilters |
280 | |
281 | This property holds the filters that restrict the types of files that |
282 | can be selected. |
283 | |
284 | \code |
285 | FileDialog { |
286 | nameFilters: ["Text files (*.txt)", "HTML files (*.html *.htm)"] |
287 | } |
288 | \endcode |
289 | |
290 | \note \b{*.*} is not a portable filter, because the historical assumption |
291 | that the file extension determines the file type is not consistent on every |
292 | operating system. It is possible to have a file with no dot in its name (for |
293 | example, \c Makefile). In a native Windows file dialog, \b{*.*} will match |
294 | such files, while in other types of file dialogs it may not. So it is better |
295 | to use \b{*} if you mean to select any file. |
296 | |
297 | \sa selectedNameFilter |
298 | */ |
299 | QStringList QQuickLabsPlatformFileDialog::nameFilters() const |
300 | { |
301 | return m_options->nameFilters(); |
302 | } |
303 | |
304 | void QQuickLabsPlatformFileDialog::setNameFilters(const QStringList &filters) |
305 | { |
306 | if (filters == m_options->nameFilters()) |
307 | return; |
308 | |
309 | m_options->setNameFilters(filters); |
310 | if (m_selectedNameFilter) { |
311 | int index = m_selectedNameFilter->index(); |
312 | if (index < 0 || index >= filters.size()) |
313 | index = 0; |
314 | m_selectedNameFilter->update(filter: filters.value(i: index)); |
315 | } |
316 | emit nameFiltersChanged(); |
317 | } |
318 | |
319 | void QQuickLabsPlatformFileDialog::resetNameFilters() |
320 | { |
321 | setNameFilters(QStringList()); |
322 | } |
323 | |
324 | /*! |
325 | \qmlproperty int Qt.labs.platform::FileDialog::selectedNameFilter.index |
326 | \qmlproperty string Qt.labs.platform::FileDialog::selectedNameFilter.name |
327 | \qmlproperty list<string> Qt.labs.platform::FileDialog::selectedNameFilter.extensions |
328 | |
329 | These properties hold the currently selected name filter. |
330 | |
331 | \table |
332 | \header |
333 | \li Name |
334 | \li Description |
335 | \row |
336 | \li \b index : int |
337 | \li This property determines which \l {nameFilters}{name filter} is selected. |
338 | The specified filter is selected when the dialog is opened. The value is |
339 | updated when the user selects another filter. |
340 | \row |
341 | \li [read-only] \b name : string |
342 | \li This property holds the name of the selected filter. In the |
343 | example below, the name of the first filter is \c {"Text files"} |
344 | and the second is \c {"HTML files"}. |
345 | \row |
346 | \li [read-only] \b extensions : list<string> |
347 | \li This property holds the list of extensions of the selected filter. |
348 | In the example below, the list of extensions of the first filter is |
349 | \c {["txt"]} and the second is \c {["html", "htm"]}. |
350 | \endtable |
351 | |
352 | \code |
353 | FileDialog { |
354 | id: fileDialog |
355 | selectedNameFilter.index: 1 |
356 | nameFilters: ["Text files (*.txt)", "HTML files (*.html *.htm)"] |
357 | } |
358 | |
359 | MyDocument { |
360 | id: document |
361 | fileType: fileDialog.selectedNameFilter.extensions[0] |
362 | } |
363 | \endcode |
364 | |
365 | \sa nameFilters |
366 | */ |
367 | QQuickLabsPlatformFileNameFilter *QQuickLabsPlatformFileDialog::selectedNameFilter() const |
368 | { |
369 | if (!m_selectedNameFilter) { |
370 | QQuickLabsPlatformFileDialog *that = const_cast<QQuickLabsPlatformFileDialog *>(this); |
371 | m_selectedNameFilter = new QQuickLabsPlatformFileNameFilter(that); |
372 | m_selectedNameFilter->setOptions(m_options); |
373 | } |
374 | return m_selectedNameFilter; |
375 | } |
376 | |
377 | /*! |
378 | \qmlproperty string Qt.labs.platform::FileDialog::defaultSuffix |
379 | |
380 | This property holds a suffix that is added to selected files that have |
381 | no suffix specified. The suffix is typically used to indicate the file |
382 | type (e.g. "txt" indicates a text file). |
383 | |
384 | If the first character is a dot ('.'), it is removed. |
385 | */ |
386 | QString QQuickLabsPlatformFileDialog::defaultSuffix() const |
387 | { |
388 | return m_options->defaultSuffix(); |
389 | } |
390 | |
391 | void QQuickLabsPlatformFileDialog::setDefaultSuffix(const QString &suffix) |
392 | { |
393 | if (suffix == m_options->defaultSuffix()) |
394 | return; |
395 | |
396 | m_options->setDefaultSuffix(suffix); |
397 | emit defaultSuffixChanged(); |
398 | } |
399 | |
400 | void QQuickLabsPlatformFileDialog::resetDefaultSuffix() |
401 | { |
402 | setDefaultSuffix(QString()); |
403 | } |
404 | |
405 | /*! |
406 | \qmlproperty string Qt.labs.platform::FileDialog::acceptLabel |
407 | |
408 | This property holds the label text shown on the button that accepts the dialog. |
409 | |
410 | When set to an empty string, the default label of the underlying platform is used. |
411 | The default label is typically \uicontrol Open or \uicontrol Save depending on which |
412 | \l fileMode the dialog is used in. |
413 | |
414 | The default value is an empty string. |
415 | |
416 | \sa rejectLabel |
417 | */ |
418 | QString QQuickLabsPlatformFileDialog::acceptLabel() const |
419 | { |
420 | return m_options->labelText(label: QFileDialogOptions::Accept); |
421 | } |
422 | |
423 | void QQuickLabsPlatformFileDialog::setAcceptLabel(const QString &label) |
424 | { |
425 | if (label == m_options->labelText(label: QFileDialogOptions::Accept)) |
426 | return; |
427 | |
428 | m_options->setLabelText(label: QFileDialogOptions::Accept, text: label); |
429 | emit acceptLabelChanged(); |
430 | } |
431 | |
432 | void QQuickLabsPlatformFileDialog::resetAcceptLabel() |
433 | { |
434 | setAcceptLabel(QString()); |
435 | } |
436 | |
437 | /*! |
438 | \qmlproperty string Qt.labs.platform::FileDialog::rejectLabel |
439 | |
440 | This property holds the label text shown on the button that rejects the dialog. |
441 | |
442 | When set to an empty string, the default label of the underlying platform is used. |
443 | The default label is typically \uicontrol Cancel. |
444 | |
445 | The default value is an empty string. |
446 | |
447 | \sa acceptLabel |
448 | */ |
449 | QString QQuickLabsPlatformFileDialog::rejectLabel() const |
450 | { |
451 | return m_options->labelText(label: QFileDialogOptions::Reject); |
452 | } |
453 | |
454 | void QQuickLabsPlatformFileDialog::setRejectLabel(const QString &label) |
455 | { |
456 | if (label == m_options->labelText(label: QFileDialogOptions::Reject)) |
457 | return; |
458 | |
459 | m_options->setLabelText(label: QFileDialogOptions::Reject, text: label); |
460 | emit rejectLabelChanged(); |
461 | } |
462 | |
463 | void QQuickLabsPlatformFileDialog::resetRejectLabel() |
464 | { |
465 | setRejectLabel(QString()); |
466 | } |
467 | |
468 | bool QQuickLabsPlatformFileDialog::useNativeDialog() const |
469 | { |
470 | return QQuickLabsPlatformDialog::useNativeDialog() |
471 | && !m_options->testOption(option: QFileDialogOptions::DontUseNativeDialog); |
472 | } |
473 | |
474 | void QQuickLabsPlatformFileDialog::onCreate(QPlatformDialogHelper *dialog) |
475 | { |
476 | if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(object: dialog)) { |
477 | // TODO: emit currentFileChanged only when the first entry in currentFiles changes |
478 | connect(sender: fileDialog, signal: &QPlatformFileDialogHelper::currentChanged, context: this, slot: &QQuickLabsPlatformFileDialog::currentFileChanged); |
479 | connect(sender: fileDialog, signal: &QPlatformFileDialogHelper::currentChanged, context: this, slot: &QQuickLabsPlatformFileDialog::currentFilesChanged); |
480 | connect(sender: fileDialog, signal: &QPlatformFileDialogHelper::directoryEntered, context: this, slot: &QQuickLabsPlatformFileDialog::folderChanged); |
481 | fileDialog->setOptions(m_options); |
482 | } |
483 | } |
484 | |
485 | void QQuickLabsPlatformFileDialog::onShow(QPlatformDialogHelper *dialog) |
486 | { |
487 | m_options->setWindowTitle(title()); |
488 | if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(object: dialog)) { |
489 | fileDialog->setOptions(m_options); // setOptions only assigns a member and isn't virtual |
490 | if (m_firstShow && m_options->initialDirectory().isValid()) |
491 | fileDialog->setDirectory(m_options->initialDirectory()); |
492 | if (m_selectedNameFilter) { |
493 | const int index = m_selectedNameFilter->index(); |
494 | const QString filter = m_options->nameFilters().value(i: index); |
495 | m_options->setInitiallySelectedNameFilter(filter); |
496 | fileDialog->selectNameFilter(filter); |
497 | connect(sender: fileDialog, signal: &QPlatformFileDialogHelper::filterSelected, context: m_selectedNameFilter, slot: &QQuickLabsPlatformFileNameFilter::update); |
498 | } |
499 | } |
500 | if (m_firstShow) |
501 | m_firstShow = false; |
502 | } |
503 | |
504 | void QQuickLabsPlatformFileDialog::onHide(QPlatformDialogHelper *dialog) |
505 | { |
506 | if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(object: dialog)) { |
507 | if (m_selectedNameFilter) |
508 | disconnect(sender: fileDialog, signal: &QPlatformFileDialogHelper::filterSelected, receiver: m_selectedNameFilter, slot: &QQuickLabsPlatformFileNameFilter::update); |
509 | } |
510 | } |
511 | |
512 | void QQuickLabsPlatformFileDialog::accept() |
513 | { |
514 | if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(object: handle())) |
515 | setFiles(fileDialog->selectedFiles()); |
516 | QQuickLabsPlatformDialog::accept(); |
517 | } |
518 | |
519 | QUrl QQuickLabsPlatformFileDialog::addDefaultSuffix(const QUrl &file) const |
520 | { |
521 | QUrl url = file; |
522 | const QString path = url.path(); |
523 | const QString suffix = m_options->defaultSuffix(); |
524 | // Urls with "content" scheme do not require suffixes. Such schemes are |
525 | // used on Android. |
526 | const bool isContentScheme = url.scheme() == u"content"_s ; |
527 | if (!isContentScheme && !suffix.isEmpty() && !path.endsWith(c: QLatin1Char('/')) |
528 | && path.lastIndexOf(c: QLatin1Char('.')) == -1) { |
529 | url.setPath(path: path + QLatin1Char('.') + suffix); |
530 | } |
531 | return url; |
532 | } |
533 | |
534 | QList<QUrl> QQuickLabsPlatformFileDialog::addDefaultSuffixes(const QList<QUrl> &files) const |
535 | { |
536 | QList<QUrl> urls; |
537 | urls.reserve(asize: files.size()); |
538 | for (const QUrl &file : files) |
539 | urls += addDefaultSuffix(file); |
540 | return urls; |
541 | } |
542 | |
543 | QQuickLabsPlatformFileNameFilter::QQuickLabsPlatformFileNameFilter(QObject *parent) |
544 | : QObject(parent), m_index(-1) |
545 | { |
546 | } |
547 | |
548 | int QQuickLabsPlatformFileNameFilter::index() const |
549 | { |
550 | return m_index; |
551 | } |
552 | |
553 | void QQuickLabsPlatformFileNameFilter::setIndex(int index) |
554 | { |
555 | if (m_index == index) |
556 | return; |
557 | |
558 | m_index = index; |
559 | emit indexChanged(index); |
560 | } |
561 | |
562 | QString QQuickLabsPlatformFileNameFilter::name() const |
563 | { |
564 | return m_name; |
565 | } |
566 | |
567 | QStringList QQuickLabsPlatformFileNameFilter::extensions() const |
568 | { |
569 | return m_extensions; |
570 | } |
571 | |
572 | QSharedPointer<QFileDialogOptions> QQuickLabsPlatformFileNameFilter::options() const |
573 | { |
574 | return m_options; |
575 | } |
576 | |
577 | void QQuickLabsPlatformFileNameFilter::setOptions(const QSharedPointer<QFileDialogOptions> &options) |
578 | { |
579 | m_options = options; |
580 | } |
581 | |
582 | static QString (const QString &filter) |
583 | { |
584 | return filter.left(n: filter.indexOf(c: QLatin1Char('(')) - 1); |
585 | } |
586 | |
587 | static QString (QStringView filter) |
588 | { |
589 | return filter.mid(pos: filter.indexOf(c: QLatin1Char('.')) + 1).toString(); |
590 | } |
591 | |
592 | static QStringList (QStringView filter) |
593 | { |
594 | QStringList extensions; |
595 | const int from = filter.indexOf(c: QLatin1Char('(')); |
596 | const int to = filter.lastIndexOf(c: QLatin1Char(')')) - 1; |
597 | if (from >= 0 && from < to) { |
598 | const QStringView ref = filter.mid(pos: from + 1, n: to - from); |
599 | const QList<QStringView> exts = ref.split(sep: QLatin1Char(' '), behavior: Qt::SkipEmptyParts); |
600 | for (const QStringView &ref : exts) |
601 | extensions += extractExtension(filter: ref); |
602 | } |
603 | |
604 | return extensions; |
605 | } |
606 | |
607 | void QQuickLabsPlatformFileNameFilter::update(const QString &filter) |
608 | { |
609 | const QStringList filters = nameFilters(); |
610 | |
611 | const int oldIndex = m_index; |
612 | const QString oldName = m_name; |
613 | const QStringList oldExtensions = m_extensions; |
614 | |
615 | m_index = filters.indexOf(str: filter); |
616 | m_name = extractName(filter); |
617 | m_extensions = extractExtensions(filter); |
618 | |
619 | if (oldIndex != m_index) |
620 | emit indexChanged(index: m_index); |
621 | if (oldName != m_name) |
622 | emit nameChanged(name: m_name); |
623 | if (oldExtensions != m_extensions) |
624 | emit extensionsChanged(extensions: m_extensions); |
625 | } |
626 | |
627 | QStringList QQuickLabsPlatformFileNameFilter::nameFilters() const |
628 | { |
629 | return m_options ? m_options->nameFilters() : QStringList(); |
630 | } |
631 | |
632 | QString QQuickLabsPlatformFileNameFilter::nameFilter(int index) const |
633 | { |
634 | return m_options ? m_options->nameFilters().value(i: index) : QString(); |
635 | } |
636 | |
637 | QT_END_NAMESPACE |
638 | |
639 | #include "moc_qquicklabsplatformfiledialog_p.cpp" |
640 | |