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

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