1// Copyright (C) 2018 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 "qplatformdialoghelper.h"
5
6#include <QtCore/QCoreApplication>
7#include <QtCore/QList>
8#if QT_CONFIG(regularexpression)
9#include <QtCore/QRegularExpression>
10#endif
11#if QT_CONFIG(settings)
12#include <QtCore/QSettings>
13#endif
14#include <QtCore/QSharedData>
15#include <QtCore/QUrl>
16#include <QtCore/QVariant>
17#include <QtGui/QColor>
18#include <QtGui/QPixmap>
19
20#include <algorithm>
21
22QT_BEGIN_NAMESPACE
23
24using namespace Qt::StringLiterals;
25
26QT_IMPL_METATYPE_EXTERN_TAGGED(QPlatformDialogHelper::StandardButton,
27 QPlatformDialogHelper__StandardButton)
28QT_IMPL_METATYPE_EXTERN_TAGGED(QPlatformDialogHelper::ButtonRole,
29 QPlatformDialogHelper__ButtonRole)
30
31/*!
32 \class QPlatformDialogHelper
33 \since 5.0
34 \internal
35 \ingroup qpa
36
37 \brief The QPlatformDialogHelper class allows for platform-specific customization of dialogs.
38
39*/
40
41/*!
42 \enum QPlatformDialogHelper::StyleHint
43
44 This enum type specifies platform-specific style hints.
45
46 \value DialogIsQtWindow Indicates that a platform-specific dialog is implemented
47 as in-process Qt window. It allows to prevent blocking the
48 dialog by an invisible proxy Qt dialog.
49
50 \sa styleHint()
51*/
52
53static const int buttonRoleLayouts[2][6][14] =
54{
55 // Qt::Horizontal
56 {
57 // WinLayout
58 { QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::YesRole, QPlatformDialogHelper::AcceptRole,
59 QPlatformDialogHelper::AlternateRole, QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::NoRole,
60 QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::RejectRole, QPlatformDialogHelper::ApplyRole,
61 QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
62
63 // MacLayout
64 { QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ActionRole,
65 QPlatformDialogHelper::Stretch, QPlatformDialogHelper::DestructiveRole | QPlatformDialogHelper::Reverse,
66 QPlatformDialogHelper::AlternateRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::RejectRole | QPlatformDialogHelper::Reverse,
67 QPlatformDialogHelper::AcceptRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::NoRole | QPlatformDialogHelper::Reverse,
68 QPlatformDialogHelper::YesRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
69
70 // KdeLayout
71 { QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::YesRole,
72 QPlatformDialogHelper::NoRole, QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::AlternateRole,
73 QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::RejectRole, QPlatformDialogHelper::EOL },
74
75 // GnomeLayout
76 { QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::ActionRole,
77 QPlatformDialogHelper::ApplyRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::DestructiveRole | QPlatformDialogHelper::Reverse,
78 QPlatformDialogHelper::AlternateRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::RejectRole | QPlatformDialogHelper::Reverse,
79 QPlatformDialogHelper::AcceptRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::NoRole | QPlatformDialogHelper::Reverse,
80 QPlatformDialogHelper::YesRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::EOL },
81
82 // AndroidLayout (neutral, stretch, dismissive, affirmative)
83 // https://material.io/guidelines/components/dialogs.html#dialogs-specs
84 { QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ActionRole,
85 QPlatformDialogHelper::Stretch, QPlatformDialogHelper::RejectRole | QPlatformDialogHelper::Reverse,
86 QPlatformDialogHelper::NoRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::DestructiveRole | QPlatformDialogHelper::Reverse,
87 QPlatformDialogHelper::AlternateRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::AcceptRole | QPlatformDialogHelper::Reverse,
88 QPlatformDialogHelper::YesRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL }
89 },
90
91 // Qt::Vertical
92 {
93 // WinLayout
94 { QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::YesRole, QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::AlternateRole,
95 QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::NoRole, QPlatformDialogHelper::RejectRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ResetRole,
96 QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
97
98 // MacLayout
99 { QPlatformDialogHelper::YesRole, QPlatformDialogHelper::NoRole, QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::RejectRole,
100 QPlatformDialogHelper::AlternateRole, QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::ApplyRole,
101 QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
102
103 // KdeLayout
104 { QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::AlternateRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ActionRole,
105 QPlatformDialogHelper::YesRole, QPlatformDialogHelper::NoRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::ResetRole,
106 QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::RejectRole, QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL },
107
108 // GnomeLayout
109 { QPlatformDialogHelper::YesRole, QPlatformDialogHelper::NoRole, QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::RejectRole,
110 QPlatformDialogHelper::AlternateRole, QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::Stretch,
111 QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
112
113 // AndroidLayout
114 // (affirmative
115 // dismissive
116 // neutral)
117 // https://material.io/guidelines/components/dialogs.html#dialogs-specs
118 { QPlatformDialogHelper::YesRole, QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::AlternateRole, QPlatformDialogHelper::DestructiveRole,
119 QPlatformDialogHelper::NoRole, QPlatformDialogHelper::RejectRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::ApplyRole,
120 QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL }
121 }
122};
123
124
125QPlatformDialogHelper::QPlatformDialogHelper()
126{
127 qRegisterMetaType<StandardButton>();
128 qRegisterMetaType<ButtonRole>();
129}
130
131QPlatformDialogHelper::~QPlatformDialogHelper()
132{
133}
134
135QVariant QPlatformDialogHelper::styleHint(StyleHint hint) const
136{
137 return QPlatformDialogHelper::defaultStyleHint(hint);
138}
139
140QVariant QPlatformDialogHelper::defaultStyleHint(QPlatformDialogHelper::StyleHint hint)
141{
142 Q_UNUSED(hint);
143 return QVariant();
144}
145
146// Font dialog
147
148class QFontDialogOptionsPrivate : public QSharedData
149{
150public:
151 QFontDialogOptionsPrivate() = default;
152
153 QFontDialogOptions::FontDialogOptions options;
154 QString windowTitle;
155};
156
157QFontDialogOptions::QFontDialogOptions(QFontDialogOptionsPrivate *dd)
158 : d(dd)
159{
160}
161
162QFontDialogOptions::~QFontDialogOptions()
163{
164}
165
166namespace {
167 struct FontDialogCombined : QFontDialogOptionsPrivate, QFontDialogOptions
168 {
169 FontDialogCombined() : QFontDialogOptionsPrivate(), QFontDialogOptions(this) {}
170 FontDialogCombined(const FontDialogCombined &other)
171 : QFontDialogOptionsPrivate(other), QFontDialogOptions(this) {}
172 };
173}
174
175// static
176QSharedPointer<QFontDialogOptions> QFontDialogOptions::create()
177{
178 return QSharedPointer<FontDialogCombined>::create();
179}
180
181QSharedPointer<QFontDialogOptions> QFontDialogOptions::clone() const
182{
183 return QSharedPointer<FontDialogCombined>::create(arguments: *static_cast<const FontDialogCombined*>(this));
184}
185
186QString QFontDialogOptions::windowTitle() const
187{
188 return d->windowTitle;
189}
190
191void QFontDialogOptions::setWindowTitle(const QString &title)
192{
193 d->windowTitle = title;
194}
195
196void QFontDialogOptions::setOption(QFontDialogOptions::FontDialogOption option, bool on)
197{
198 if (!(d->options & option) != !on)
199 setOptions(d->options ^ option);
200}
201
202bool QFontDialogOptions::testOption(QFontDialogOptions::FontDialogOption option) const
203{
204 return d->options & option;
205}
206
207void QFontDialogOptions::setOptions(FontDialogOptions options)
208{
209 if (options != d->options)
210 d->options = options;
211}
212
213QFontDialogOptions::FontDialogOptions QFontDialogOptions::options() const
214{
215 return d->options;
216}
217
218/*!
219 \class QPlatformFontDialogHelper
220 \since 5.0
221 \internal
222 \ingroup qpa
223
224 \brief The QPlatformFontDialogHelper class allows for platform-specific customization of font dialogs.
225
226*/
227const QSharedPointer<QFontDialogOptions> &QPlatformFontDialogHelper::options() const
228{
229 return m_options;
230}
231
232void QPlatformFontDialogHelper::setOptions(const QSharedPointer<QFontDialogOptions> &options)
233{
234 m_options = options;
235}
236
237// Color dialog
238
239class QColorDialogStaticData
240{
241public:
242 enum { CustomColorCount = 16, StandardColorCount = 6 * 8 };
243
244 QColorDialogStaticData();
245 inline void readSettings();
246 inline void writeSettings() const;
247
248 QRgb customRgb[CustomColorCount];
249 QRgb standardRgb[StandardColorCount];
250 bool customSet;
251};
252
253QColorDialogStaticData::QColorDialogStaticData() : customSet(false)
254{
255 int i = 0;
256 for (int g = 0; g < 4; ++g)
257 for (int r = 0; r < 4; ++r)
258 for (int b = 0; b < 3; ++b)
259 standardRgb[i++] = qRgb(r: r * 255 / 3, g: g * 255 / 3, b: b * 255 / 2);
260 std::fill(customRgb, customRgb + CustomColorCount, 0xffffffff);
261 readSettings();
262}
263
264void QColorDialogStaticData::readSettings()
265{
266#if QT_CONFIG(settings)
267 const QSettings settings(QSettings::UserScope, QStringLiteral("QtProject"));
268 for (int i = 0; i < int(CustomColorCount); ++i) {
269 const QVariant v = settings.value(key: "Qt/customColors/"_L1 + QString::number(i));
270 if (v.isValid())
271 customRgb[i] = v.toUInt();
272 }
273#endif
274}
275
276void QColorDialogStaticData::writeSettings() const
277{
278#if QT_CONFIG(settings)
279 if (customSet) {
280 const_cast<QColorDialogStaticData*>(this)->customSet = false;
281 QSettings settings(QSettings::UserScope, QStringLiteral("QtProject"));
282 for (int i = 0; i < int(CustomColorCount); ++i)
283 settings.setValue(key: "Qt/customColors/"_L1 + QString::number(i), value: customRgb[i]);
284 }
285#endif
286}
287
288Q_GLOBAL_STATIC(QColorDialogStaticData, qColorDialogStaticData)
289
290class QColorDialogOptionsPrivate : public QSharedData
291{
292public:
293 QColorDialogOptionsPrivate() = default;
294 // Write out settings around destruction of dialogs
295 ~QColorDialogOptionsPrivate() { qColorDialogStaticData()->writeSettings(); }
296
297 QColorDialogOptions::ColorDialogOptions options;
298 QString windowTitle;
299};
300
301QColorDialogOptions::QColorDialogOptions(QColorDialogOptionsPrivate *dd)
302 : d(dd)
303{
304}
305
306QColorDialogOptions::~QColorDialogOptions()
307{
308}
309
310namespace {
311 struct ColorDialogCombined : QColorDialogOptionsPrivate, QColorDialogOptions
312 {
313 ColorDialogCombined() : QColorDialogOptionsPrivate(), QColorDialogOptions(this) {}
314 ColorDialogCombined(const ColorDialogCombined &other)
315 : QColorDialogOptionsPrivate(other), QColorDialogOptions(this) {}
316 };
317}
318
319// static
320QSharedPointer<QColorDialogOptions> QColorDialogOptions::create()
321{
322 return QSharedPointer<ColorDialogCombined>::create();
323}
324
325QSharedPointer<QColorDialogOptions> QColorDialogOptions::clone() const
326{
327 return QSharedPointer<ColorDialogCombined>::create(arguments: *static_cast<const ColorDialogCombined*>(this));
328}
329
330QString QColorDialogOptions::windowTitle() const
331{
332 return d->windowTitle;
333}
334
335void QColorDialogOptions::setWindowTitle(const QString &title)
336{
337 d->windowTitle = title;
338}
339
340void QColorDialogOptions::setOption(QColorDialogOptions::ColorDialogOption option, bool on)
341{
342 if (!(d->options & option) != !on)
343 setOptions(d->options ^ option);
344}
345
346bool QColorDialogOptions::testOption(QColorDialogOptions::ColorDialogOption option) const
347{
348 return d->options & option;
349}
350
351void QColorDialogOptions::setOptions(ColorDialogOptions options)
352{
353 if (options != d->options)
354 d->options = options;
355}
356
357QColorDialogOptions::ColorDialogOptions QColorDialogOptions::options() const
358{
359 return d->options;
360}
361
362int QColorDialogOptions::customColorCount()
363{
364 return QColorDialogStaticData::CustomColorCount;
365}
366
367QRgb QColorDialogOptions::customColor(int index)
368{
369 if (uint(index) >= uint(QColorDialogStaticData::CustomColorCount))
370 return qRgb(r: 255, g: 255, b: 255);
371 return qColorDialogStaticData()->customRgb[index];
372}
373
374QRgb *QColorDialogOptions::customColors()
375{
376 return qColorDialogStaticData()->customRgb;
377}
378
379void QColorDialogOptions::setCustomColor(int index, QRgb color)
380{
381 if (uint(index) >= uint(QColorDialogStaticData::CustomColorCount))
382 return;
383 qColorDialogStaticData()->customSet = true;
384 qColorDialogStaticData()->customRgb[index] = color;
385}
386
387QRgb *QColorDialogOptions::standardColors()
388{
389 return qColorDialogStaticData()->standardRgb;
390}
391
392QRgb QColorDialogOptions::standardColor(int index)
393{
394 if (uint(index) >= uint(QColorDialogStaticData::StandardColorCount))
395 return qRgb(r: 255, g: 255, b: 255);
396 return qColorDialogStaticData()->standardRgb[index];
397}
398
399void QColorDialogOptions::setStandardColor(int index, QRgb color)
400{
401 if (uint(index) >= uint(QColorDialogStaticData::StandardColorCount))
402 return;
403 qColorDialogStaticData()->standardRgb[index] = color;
404}
405
406/*!
407 \class QPlatformColorDialogHelper
408 \since 5.0
409 \internal
410 \ingroup qpa
411
412 \brief The QPlatformColorDialogHelper class allows for platform-specific customization of color dialogs.
413
414*/
415const QSharedPointer<QColorDialogOptions> &QPlatformColorDialogHelper::options() const
416{
417 return m_options;
418}
419
420void QPlatformColorDialogHelper::setOptions(const QSharedPointer<QColorDialogOptions> &options)
421{
422 m_options = options;
423}
424
425// File dialog
426
427class QFileDialogOptionsPrivate : public QSharedData
428{
429public:
430 QFileDialogOptions::FileDialogOptions options;
431 QString windowTitle;
432
433 QFileDialogOptions::ViewMode viewMode = QFileDialogOptions::Detail;
434 QFileDialogOptions::FileMode fileMode = QFileDialogOptions::AnyFile;
435 QFileDialogOptions::AcceptMode acceptMode = QFileDialogOptions::AcceptOpen;
436 QString labels[QFileDialogOptions::DialogLabelCount];
437 QDir::Filters filters = QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs;
438 QList<QUrl> sidebarUrls;
439 bool useDefaultNameFilters = true;
440 QStringList nameFilters;
441 QStringList mimeTypeFilters;
442 QString defaultSuffix;
443 QStringList history;
444 QUrl initialDirectory;
445 QString initiallySelectedMimeTypeFilter;
446 QString initiallySelectedNameFilter;
447 QList<QUrl> initiallySelectedFiles;
448 QStringList supportedSchemes;
449};
450
451QFileDialogOptions::QFileDialogOptions(QFileDialogOptionsPrivate *dd)
452 : d(dd)
453{
454}
455
456QFileDialogOptions::~QFileDialogOptions()
457{
458}
459
460namespace {
461 struct FileDialogCombined : QFileDialogOptionsPrivate, QFileDialogOptions
462 {
463 FileDialogCombined() : QFileDialogOptionsPrivate(), QFileDialogOptions(this) {}
464 FileDialogCombined(const FileDialogCombined &other) : QFileDialogOptionsPrivate(other), QFileDialogOptions(this) {}
465 };
466}
467
468// static
469QSharedPointer<QFileDialogOptions> QFileDialogOptions::create()
470{
471 return QSharedPointer<FileDialogCombined>::create();
472}
473
474QSharedPointer<QFileDialogOptions> QFileDialogOptions::clone() const
475{
476 return QSharedPointer<FileDialogCombined>::create(arguments: *static_cast<const FileDialogCombined*>(this));
477}
478
479QString QFileDialogOptions::windowTitle() const
480{
481 return d->windowTitle;
482}
483
484void QFileDialogOptions::setWindowTitle(const QString &title)
485{
486 d->windowTitle = title;
487}
488
489void QFileDialogOptions::setOption(QFileDialogOptions::FileDialogOption option, bool on)
490{
491 if (!(d->options & option) != !on)
492 setOptions(d->options ^ option);
493}
494
495bool QFileDialogOptions::testOption(QFileDialogOptions::FileDialogOption option) const
496{
497 return d->options & option;
498}
499
500void QFileDialogOptions::setOptions(FileDialogOptions options)
501{
502 if (options != d->options)
503 d->options = options;
504}
505
506QFileDialogOptions::FileDialogOptions QFileDialogOptions::options() const
507{
508 return d->options;
509}
510
511QDir::Filters QFileDialogOptions::filter() const
512{
513 return d->filters;
514}
515
516void QFileDialogOptions::setFilter(QDir::Filters filters)
517{
518 d->filters = filters;
519}
520
521void QFileDialogOptions::setViewMode(QFileDialogOptions::ViewMode mode)
522{
523 d->viewMode = mode;
524}
525
526QFileDialogOptions::ViewMode QFileDialogOptions::viewMode() const
527{
528 return d->viewMode;
529}
530
531void QFileDialogOptions::setFileMode(QFileDialogOptions::FileMode mode)
532{
533 d->fileMode = mode;
534}
535
536QFileDialogOptions::FileMode QFileDialogOptions::fileMode() const
537{
538 return d->fileMode;
539}
540
541void QFileDialogOptions::setAcceptMode(QFileDialogOptions::AcceptMode mode)
542{
543 d->acceptMode = mode;
544}
545
546QFileDialogOptions::AcceptMode QFileDialogOptions::acceptMode() const
547{
548 return d->acceptMode;
549}
550
551void QFileDialogOptions::setSidebarUrls(const QList<QUrl> &urls)
552{
553 d->sidebarUrls = urls;
554}
555
556QList<QUrl> QFileDialogOptions::sidebarUrls() const
557{
558 return d->sidebarUrls;
559}
560
561/*!
562 \since 5.7
563 \internal
564 The bool property useDefaultNameFilters indicates that no name filters have been
565 set or that they are equivalent to \gui{All Files (*)}. If it is true, the
566 platform can choose to hide the filter combo box.
567
568 \sa defaultNameFilterString().
569*/
570bool QFileDialogOptions::useDefaultNameFilters() const
571{
572 return d->useDefaultNameFilters;
573}
574
575void QFileDialogOptions::setUseDefaultNameFilters(bool dnf)
576{
577 d->useDefaultNameFilters = dnf;
578}
579
580void QFileDialogOptions::setNameFilters(const QStringList &filters)
581{
582 d->useDefaultNameFilters = filters.size() == 1
583 && filters.first() == QFileDialogOptions::defaultNameFilterString();
584 d->nameFilters = filters;
585}
586
587QStringList QFileDialogOptions::nameFilters() const
588{
589 return d->useDefaultNameFilters ?
590 QStringList(QFileDialogOptions::defaultNameFilterString()) : d->nameFilters;
591}
592
593/*!
594 \since 5.6
595 \internal
596 \return The translated default name filter string (\gui{All Files (*)}).
597 \sa defaultNameFilters(), nameFilters()
598*/
599
600QString QFileDialogOptions::defaultNameFilterString()
601{
602 return QCoreApplication::translate(context: "QFileDialog", key: "All Files (*)");
603}
604
605void QFileDialogOptions::setMimeTypeFilters(const QStringList &filters)
606{
607 d->mimeTypeFilters = filters;
608}
609
610QStringList QFileDialogOptions::mimeTypeFilters() const
611{
612 return d->mimeTypeFilters;
613}
614
615void QFileDialogOptions::setDefaultSuffix(const QString &suffix)
616{
617 d->defaultSuffix = suffix;
618 if (d->defaultSuffix.size() > 1 && d->defaultSuffix.startsWith(c: u'.'))
619 d->defaultSuffix.remove(i: 0, len: 1); // Silently change ".txt" -> "txt".
620}
621
622QString QFileDialogOptions::defaultSuffix() const
623{
624 return d->defaultSuffix;
625}
626
627void QFileDialogOptions::setHistory(const QStringList &paths)
628{
629 d->history = paths;
630}
631
632QStringList QFileDialogOptions::history() const
633{
634 return d->history;
635}
636
637void QFileDialogOptions::setLabelText(QFileDialogOptions::DialogLabel label, const QString &text)
638{
639 if (unsigned(label) < unsigned(DialogLabelCount))
640 d->labels[label] = text;
641}
642
643QString QFileDialogOptions::labelText(QFileDialogOptions::DialogLabel label) const
644{
645 return (unsigned(label) < unsigned(DialogLabelCount)) ? d->labels[label] : QString();
646}
647
648bool QFileDialogOptions::isLabelExplicitlySet(DialogLabel label)
649{
650 return unsigned(label) < unsigned(DialogLabelCount) && !d->labels[label].isEmpty();
651}
652
653QUrl QFileDialogOptions::initialDirectory() const
654{
655 return d->initialDirectory;
656}
657
658void QFileDialogOptions::setInitialDirectory(const QUrl &directory)
659{
660 d->initialDirectory = directory;
661}
662
663QString QFileDialogOptions::initiallySelectedMimeTypeFilter() const
664{
665 return d->initiallySelectedMimeTypeFilter;
666}
667
668void QFileDialogOptions::setInitiallySelectedMimeTypeFilter(const QString &filter)
669{
670 d->initiallySelectedMimeTypeFilter = filter;
671}
672
673QString QFileDialogOptions::initiallySelectedNameFilter() const
674{
675 return d->initiallySelectedNameFilter;
676}
677
678void QFileDialogOptions::setInitiallySelectedNameFilter(const QString &filter)
679{
680 d->initiallySelectedNameFilter = filter;
681}
682
683QList<QUrl> QFileDialogOptions::initiallySelectedFiles() const
684{
685 return d->initiallySelectedFiles;
686}
687
688void QFileDialogOptions::setInitiallySelectedFiles(const QList<QUrl> &files)
689{
690 d->initiallySelectedFiles = files;
691}
692
693// Schemes supported by the application
694void QFileDialogOptions::setSupportedSchemes(const QStringList &schemes)
695{
696 d->supportedSchemes = schemes;
697}
698
699QStringList QFileDialogOptions::supportedSchemes() const
700{
701 return d->supportedSchemes;
702}
703
704void QPlatformFileDialogHelper::selectMimeTypeFilter(const QString &filter)
705{
706 Q_UNUSED(filter);
707}
708
709QString QPlatformFileDialogHelper::selectedMimeTypeFilter() const
710{
711 return QString();
712}
713
714// Return true if the URL is supported by the filedialog implementation *and* by the application.
715bool QPlatformFileDialogHelper::isSupportedUrl(const QUrl &url) const
716{
717 return url.isLocalFile();
718}
719
720/*!
721 \class QPlatformFileDialogHelper
722 \since 5.0
723 \internal
724 \ingroup qpa
725
726 \brief The QPlatformFileDialogHelper class allows for platform-specific customization of file dialogs.
727
728*/
729const QSharedPointer<QFileDialogOptions> &QPlatformFileDialogHelper::options() const
730{
731 return m_options;
732}
733
734void QPlatformFileDialogHelper::setOptions(const QSharedPointer<QFileDialogOptions> &options)
735{
736 m_options = options;
737}
738
739const char QPlatformFileDialogHelper::filterRegExp[] =
740"^(.*)\\(([a-zA-Z0-9_.,*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$";
741
742// Makes a list of filters from a normal filter string "Image Files (*.png *.jpg)"
743QStringList QPlatformFileDialogHelper::cleanFilterList(const QString &filter)
744{
745#if QT_CONFIG(regularexpression)
746 static const QRegularExpression regexp(QString::fromLatin1(ba: filterRegExp));
747 Q_ASSERT(regexp.isValid());
748 QString f = filter;
749 QRegularExpressionMatch match = regexp.match(subject: filter);
750 if (match.hasMatch())
751 f = match.captured(nth: 2);
752 return f.split(sep: u' ', behavior: Qt::SkipEmptyParts);
753#else
754 Q_UNUSED(filter);
755 return QStringList();
756#endif
757}
758
759// Message dialog
760
761class QMessageDialogOptionsPrivate : public QSharedData
762{
763public:
764 QMessageDialogOptionsPrivate() :
765 icon(QMessageDialogOptions::NoIcon),
766 buttons(QPlatformDialogHelper::Ok),
767 nextCustomButtonId(QPlatformDialogHelper::LastButton + 1)
768 {}
769
770 QString windowTitle;
771 QMessageDialogOptions::StandardIcon icon;
772 QString text;
773 QString informativeText;
774 QString detailedText;
775 QPlatformDialogHelper::StandardButtons buttons;
776 QList<QMessageDialogOptions::CustomButton> customButtons;
777 int nextCustomButtonId;
778 QPixmap iconPixmap;
779 QString checkBoxLabel;
780 Qt::CheckState checkBoxState = Qt::Unchecked;
781 QMessageDialogOptions::Options options;
782};
783
784QMessageDialogOptions::QMessageDialogOptions(QMessageDialogOptionsPrivate *dd)
785 : d(dd)
786{
787}
788
789QMessageDialogOptions::~QMessageDialogOptions()
790{
791}
792
793namespace {
794 struct MessageDialogCombined : QMessageDialogOptionsPrivate, QMessageDialogOptions
795 {
796 MessageDialogCombined() : QMessageDialogOptionsPrivate(), QMessageDialogOptions(this) {}
797 MessageDialogCombined(const MessageDialogCombined &other)
798 : QMessageDialogOptionsPrivate(other), QMessageDialogOptions(this) {}
799 };
800}
801
802// static
803QSharedPointer<QMessageDialogOptions> QMessageDialogOptions::create()
804{
805 return QSharedPointer<MessageDialogCombined>::create();
806}
807
808QSharedPointer<QMessageDialogOptions> QMessageDialogOptions::clone() const
809{
810 return QSharedPointer<MessageDialogCombined>::create(arguments: *static_cast<const MessageDialogCombined*>(this));
811}
812
813QString QMessageDialogOptions::windowTitle() const
814{
815 return d->windowTitle;
816}
817
818void QMessageDialogOptions::setWindowTitle(const QString &title)
819{
820 d->windowTitle = title;
821}
822
823QMessageDialogOptions::StandardIcon QMessageDialogOptions::standardIcon() const
824{
825 return d->icon;
826}
827
828void QMessageDialogOptions::setStandardIcon(StandardIcon icon)
829{
830 d->icon = icon;
831}
832
833void QMessageDialogOptions::setIconPixmap(const QPixmap &pixmap)
834{
835 d->iconPixmap = pixmap;
836}
837
838QPixmap QMessageDialogOptions::iconPixmap() const
839{
840 return d->iconPixmap;
841}
842
843QString QMessageDialogOptions::text() const
844{
845 return d->text;
846}
847
848void QMessageDialogOptions::setText(const QString &text)
849{
850 d->text = text;
851}
852
853QString QMessageDialogOptions::informativeText() const
854{
855 return d->informativeText;
856}
857
858void QMessageDialogOptions::setInformativeText(const QString &informativeText)
859{
860 d->informativeText = informativeText;
861}
862
863QString QMessageDialogOptions::detailedText() const
864{
865 return d->detailedText;
866}
867
868void QMessageDialogOptions::setDetailedText(const QString &detailedText)
869{
870 d->detailedText = detailedText;
871}
872
873void QMessageDialogOptions::setStandardButtons(QPlatformDialogHelper::StandardButtons buttons)
874{
875 d->buttons = buttons;
876}
877
878QPlatformDialogHelper::StandardButtons QMessageDialogOptions::standardButtons() const
879{
880 return d->buttons;
881}
882
883int QMessageDialogOptions::addButton(const QString &label, QPlatformDialogHelper::ButtonRole role,
884 void *buttonImpl)
885{
886 const CustomButton b(d->nextCustomButtonId++, label, role, buttonImpl);
887 d->customButtons.append(t: b);
888 return b.id;
889}
890
891static inline bool operator==(const QMessageDialogOptions::CustomButton &a,
892 const QMessageDialogOptions::CustomButton &b) {
893 return a.id == b.id;
894}
895
896void QMessageDialogOptions::removeButton(int id)
897{
898 d->customButtons.removeOne(t: CustomButton(id));
899}
900
901const QList<QMessageDialogOptions::CustomButton> &QMessageDialogOptions::customButtons()
902{
903 return d->customButtons;
904}
905
906const QMessageDialogOptions::CustomButton *QMessageDialogOptions::customButton(int id)
907{
908 const int i = int(d->customButtons.indexOf(t: CustomButton(id)));
909 return (i < 0 ? nullptr : &d->customButtons.at(i));
910}
911
912void QMessageDialogOptions::setCheckBox(const QString &label, Qt::CheckState state)
913{
914 d->checkBoxLabel = label;
915 d->checkBoxState = state;
916}
917
918QString QMessageDialogOptions::checkBoxLabel() const
919{
920 return d->checkBoxLabel;
921}
922
923Qt::CheckState QMessageDialogOptions::checkBoxState() const
924{
925 return d->checkBoxState;
926}
927
928void QMessageDialogOptions::setOption(QMessageDialogOptions::Option option, bool on)
929{
930 if (!(d->options & option) != !on)
931 setOptions(d->options ^ option);
932}
933
934bool QMessageDialogOptions::testOption(QMessageDialogOptions::Option option) const
935{
936 return d->options & option;
937}
938
939void QMessageDialogOptions::setOptions(QMessageDialogOptions::Options options)
940{
941 if (options != d->options)
942 d->options = options;
943}
944
945QMessageDialogOptions::Options QMessageDialogOptions::options() const
946{
947 return d->options;
948}
949
950
951QPlatformDialogHelper::ButtonRole QPlatformDialogHelper::buttonRole(QPlatformDialogHelper::StandardButton button)
952{
953 switch (button) {
954 case Ok:
955 case Save:
956 case Open:
957 case SaveAll:
958 case Retry:
959 case Ignore:
960 return AcceptRole;
961
962 case Cancel:
963 case Close:
964 case Abort:
965 return RejectRole;
966
967 case Discard:
968 return DestructiveRole;
969
970 case Help:
971 return HelpRole;
972
973 case Apply:
974 return ApplyRole;
975
976 case Yes:
977 case YesToAll:
978 return YesRole;
979
980 case No:
981 case NoToAll:
982 return NoRole;
983
984 case RestoreDefaults:
985 case Reset:
986 return ResetRole;
987
988 default:
989 break;
990 }
991 return InvalidRole;
992}
993
994const int *QPlatformDialogHelper::buttonLayout(Qt::Orientation orientation, ButtonLayout policy)
995{
996 if (policy == UnknownLayout) {
997#if defined (Q_OS_MACOS)
998 policy = MacLayout;
999#elif defined (Q_OS_LINUX) || defined (Q_OS_UNIX)
1000 policy = KdeLayout;
1001#elif defined (Q_OS_ANDROID)
1002 policy = AndroidLayout;
1003#else
1004 policy = WinLayout;
1005#endif
1006 }
1007 return buttonRoleLayouts[orientation == Qt::Vertical][policy];
1008}
1009
1010/*!
1011 \class QPlatformMessageDialogHelper
1012 \since 5.0
1013 \internal
1014 \ingroup qpa
1015
1016 \brief The QPlatformMessageDialogHelper class allows for platform-specific customization of Message dialogs.
1017
1018*/
1019const QSharedPointer<QMessageDialogOptions> &QPlatformMessageDialogHelper::options() const
1020{
1021 return m_options;
1022}
1023
1024void QPlatformMessageDialogHelper::setOptions(const QSharedPointer<QMessageDialogOptions> &options)
1025{
1026 m_options = options;
1027}
1028
1029QT_END_NAMESPACE
1030
1031#include "moc_qplatformdialoghelper.cpp"
1032

source code of qtbase/src/gui/kernel/qplatformdialoghelper.cpp