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 | |
22 | QT_BEGIN_NAMESPACE |
23 | |
24 | using namespace Qt::StringLiterals; |
25 | |
26 | QT_IMPL_METATYPE_EXTERN_TAGGED(QPlatformDialogHelper::StandardButton, |
27 | QPlatformDialogHelper__StandardButton) |
28 | QT_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 | |
53 | static 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 | |
125 | QPlatformDialogHelper::QPlatformDialogHelper() |
126 | { |
127 | qRegisterMetaType<StandardButton>(); |
128 | qRegisterMetaType<ButtonRole>(); |
129 | } |
130 | |
131 | QPlatformDialogHelper::~QPlatformDialogHelper() |
132 | { |
133 | } |
134 | |
135 | QVariant QPlatformDialogHelper::styleHint(StyleHint hint) const |
136 | { |
137 | return QPlatformDialogHelper::defaultStyleHint(hint); |
138 | } |
139 | |
140 | QVariant QPlatformDialogHelper::defaultStyleHint(QPlatformDialogHelper::StyleHint hint) |
141 | { |
142 | Q_UNUSED(hint); |
143 | return QVariant(); |
144 | } |
145 | |
146 | // Font dialog |
147 | |
148 | class QFontDialogOptionsPrivate : public QSharedData |
149 | { |
150 | public: |
151 | QFontDialogOptionsPrivate() = default; |
152 | |
153 | QFontDialogOptions::FontDialogOptions options; |
154 | QString windowTitle; |
155 | }; |
156 | |
157 | QFontDialogOptions::QFontDialogOptions(QFontDialogOptionsPrivate *dd) |
158 | : d(dd) |
159 | { |
160 | } |
161 | |
162 | QFontDialogOptions::~QFontDialogOptions() |
163 | { |
164 | } |
165 | |
166 | namespace { |
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 |
176 | QSharedPointer<QFontDialogOptions> QFontDialogOptions::create() |
177 | { |
178 | return QSharedPointer<FontDialogCombined>::create(); |
179 | } |
180 | |
181 | QSharedPointer<QFontDialogOptions> QFontDialogOptions::clone() const |
182 | { |
183 | return QSharedPointer<FontDialogCombined>::create(arguments: *static_cast<const FontDialogCombined*>(this)); |
184 | } |
185 | |
186 | QString QFontDialogOptions::windowTitle() const |
187 | { |
188 | return d->windowTitle; |
189 | } |
190 | |
191 | void QFontDialogOptions::setWindowTitle(const QString &title) |
192 | { |
193 | d->windowTitle = title; |
194 | } |
195 | |
196 | void QFontDialogOptions::setOption(QFontDialogOptions::FontDialogOption option, bool on) |
197 | { |
198 | if (!(d->options & option) != !on) |
199 | setOptions(d->options ^ option); |
200 | } |
201 | |
202 | bool QFontDialogOptions::testOption(QFontDialogOptions::FontDialogOption option) const |
203 | { |
204 | return d->options & option; |
205 | } |
206 | |
207 | void QFontDialogOptions::setOptions(FontDialogOptions options) |
208 | { |
209 | if (options != d->options) |
210 | d->options = options; |
211 | } |
212 | |
213 | QFontDialogOptions::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 | */ |
227 | const QSharedPointer<QFontDialogOptions> &QPlatformFontDialogHelper::options() const |
228 | { |
229 | return m_options; |
230 | } |
231 | |
232 | void QPlatformFontDialogHelper::setOptions(const QSharedPointer<QFontDialogOptions> &options) |
233 | { |
234 | m_options = options; |
235 | } |
236 | |
237 | // Color dialog |
238 | |
239 | class QColorDialogStaticData |
240 | { |
241 | public: |
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 | |
253 | QColorDialogStaticData::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 | |
264 | void 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 | |
276 | void 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 | |
288 | Q_GLOBAL_STATIC(QColorDialogStaticData, qColorDialogStaticData) |
289 | |
290 | class QColorDialogOptionsPrivate : public QSharedData |
291 | { |
292 | public: |
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 | |
301 | QColorDialogOptions::QColorDialogOptions(QColorDialogOptionsPrivate *dd) |
302 | : d(dd) |
303 | { |
304 | } |
305 | |
306 | QColorDialogOptions::~QColorDialogOptions() |
307 | { |
308 | } |
309 | |
310 | namespace { |
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 |
320 | QSharedPointer<QColorDialogOptions> QColorDialogOptions::create() |
321 | { |
322 | return QSharedPointer<ColorDialogCombined>::create(); |
323 | } |
324 | |
325 | QSharedPointer<QColorDialogOptions> QColorDialogOptions::clone() const |
326 | { |
327 | return QSharedPointer<ColorDialogCombined>::create(arguments: *static_cast<const ColorDialogCombined*>(this)); |
328 | } |
329 | |
330 | QString QColorDialogOptions::windowTitle() const |
331 | { |
332 | return d->windowTitle; |
333 | } |
334 | |
335 | void QColorDialogOptions::setWindowTitle(const QString &title) |
336 | { |
337 | d->windowTitle = title; |
338 | } |
339 | |
340 | void QColorDialogOptions::setOption(QColorDialogOptions::ColorDialogOption option, bool on) |
341 | { |
342 | if (!(d->options & option) != !on) |
343 | setOptions(d->options ^ option); |
344 | } |
345 | |
346 | bool QColorDialogOptions::testOption(QColorDialogOptions::ColorDialogOption option) const |
347 | { |
348 | return d->options & option; |
349 | } |
350 | |
351 | void QColorDialogOptions::setOptions(ColorDialogOptions options) |
352 | { |
353 | if (options != d->options) |
354 | d->options = options; |
355 | } |
356 | |
357 | QColorDialogOptions::ColorDialogOptions QColorDialogOptions::options() const |
358 | { |
359 | return d->options; |
360 | } |
361 | |
362 | int QColorDialogOptions::customColorCount() |
363 | { |
364 | return QColorDialogStaticData::CustomColorCount; |
365 | } |
366 | |
367 | QRgb 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 | |
374 | QRgb *QColorDialogOptions::customColors() |
375 | { |
376 | return qColorDialogStaticData()->customRgb; |
377 | } |
378 | |
379 | void 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 | |
387 | QRgb *QColorDialogOptions::standardColors() |
388 | { |
389 | return qColorDialogStaticData()->standardRgb; |
390 | } |
391 | |
392 | QRgb 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 | |
399 | void 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 | */ |
415 | const QSharedPointer<QColorDialogOptions> &QPlatformColorDialogHelper::options() const |
416 | { |
417 | return m_options; |
418 | } |
419 | |
420 | void QPlatformColorDialogHelper::setOptions(const QSharedPointer<QColorDialogOptions> &options) |
421 | { |
422 | m_options = options; |
423 | } |
424 | |
425 | // File dialog |
426 | |
427 | class QFileDialogOptionsPrivate : public QSharedData |
428 | { |
429 | public: |
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 | |
451 | QFileDialogOptions::QFileDialogOptions(QFileDialogOptionsPrivate *dd) |
452 | : d(dd) |
453 | { |
454 | } |
455 | |
456 | QFileDialogOptions::~QFileDialogOptions() |
457 | { |
458 | } |
459 | |
460 | namespace { |
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 |
469 | QSharedPointer<QFileDialogOptions> QFileDialogOptions::create() |
470 | { |
471 | return QSharedPointer<FileDialogCombined>::create(); |
472 | } |
473 | |
474 | QSharedPointer<QFileDialogOptions> QFileDialogOptions::clone() const |
475 | { |
476 | return QSharedPointer<FileDialogCombined>::create(arguments: *static_cast<const FileDialogCombined*>(this)); |
477 | } |
478 | |
479 | QString QFileDialogOptions::windowTitle() const |
480 | { |
481 | return d->windowTitle; |
482 | } |
483 | |
484 | void QFileDialogOptions::setWindowTitle(const QString &title) |
485 | { |
486 | d->windowTitle = title; |
487 | } |
488 | |
489 | void QFileDialogOptions::setOption(QFileDialogOptions::FileDialogOption option, bool on) |
490 | { |
491 | if (!(d->options & option) != !on) |
492 | setOptions(d->options ^ option); |
493 | } |
494 | |
495 | bool QFileDialogOptions::testOption(QFileDialogOptions::FileDialogOption option) const |
496 | { |
497 | return d->options & option; |
498 | } |
499 | |
500 | void QFileDialogOptions::setOptions(FileDialogOptions options) |
501 | { |
502 | if (options != d->options) |
503 | d->options = options; |
504 | } |
505 | |
506 | QFileDialogOptions::FileDialogOptions QFileDialogOptions::options() const |
507 | { |
508 | return d->options; |
509 | } |
510 | |
511 | QDir::Filters QFileDialogOptions::filter() const |
512 | { |
513 | return d->filters; |
514 | } |
515 | |
516 | void QFileDialogOptions::setFilter(QDir::Filters filters) |
517 | { |
518 | d->filters = filters; |
519 | } |
520 | |
521 | void QFileDialogOptions::setViewMode(QFileDialogOptions::ViewMode mode) |
522 | { |
523 | d->viewMode = mode; |
524 | } |
525 | |
526 | QFileDialogOptions::ViewMode QFileDialogOptions::viewMode() const |
527 | { |
528 | return d->viewMode; |
529 | } |
530 | |
531 | void QFileDialogOptions::setFileMode(QFileDialogOptions::FileMode mode) |
532 | { |
533 | d->fileMode = mode; |
534 | } |
535 | |
536 | QFileDialogOptions::FileMode QFileDialogOptions::fileMode() const |
537 | { |
538 | return d->fileMode; |
539 | } |
540 | |
541 | void QFileDialogOptions::setAcceptMode(QFileDialogOptions::AcceptMode mode) |
542 | { |
543 | d->acceptMode = mode; |
544 | } |
545 | |
546 | QFileDialogOptions::AcceptMode QFileDialogOptions::acceptMode() const |
547 | { |
548 | return d->acceptMode; |
549 | } |
550 | |
551 | void QFileDialogOptions::setSidebarUrls(const QList<QUrl> &urls) |
552 | { |
553 | d->sidebarUrls = urls; |
554 | } |
555 | |
556 | QList<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 | */ |
570 | bool QFileDialogOptions::useDefaultNameFilters() const |
571 | { |
572 | return d->useDefaultNameFilters; |
573 | } |
574 | |
575 | void QFileDialogOptions::setUseDefaultNameFilters(bool dnf) |
576 | { |
577 | d->useDefaultNameFilters = dnf; |
578 | } |
579 | |
580 | void QFileDialogOptions::setNameFilters(const QStringList &filters) |
581 | { |
582 | d->useDefaultNameFilters = filters.size() == 1 |
583 | && filters.first() == QFileDialogOptions::defaultNameFilterString(); |
584 | d->nameFilters = filters; |
585 | } |
586 | |
587 | QStringList 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 | |
600 | QString QFileDialogOptions::defaultNameFilterString() |
601 | { |
602 | return QCoreApplication::translate(context: "QFileDialog", key: "All Files (*)"); |
603 | } |
604 | |
605 | void QFileDialogOptions::setMimeTypeFilters(const QStringList &filters) |
606 | { |
607 | d->mimeTypeFilters = filters; |
608 | } |
609 | |
610 | QStringList QFileDialogOptions::mimeTypeFilters() const |
611 | { |
612 | return d->mimeTypeFilters; |
613 | } |
614 | |
615 | void 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 | |
622 | QString QFileDialogOptions::defaultSuffix() const |
623 | { |
624 | return d->defaultSuffix; |
625 | } |
626 | |
627 | void QFileDialogOptions::setHistory(const QStringList &paths) |
628 | { |
629 | d->history = paths; |
630 | } |
631 | |
632 | QStringList QFileDialogOptions::history() const |
633 | { |
634 | return d->history; |
635 | } |
636 | |
637 | void QFileDialogOptions::setLabelText(QFileDialogOptions::DialogLabel label, const QString &text) |
638 | { |
639 | if (unsigned(label) < unsigned(DialogLabelCount)) |
640 | d->labels[label] = text; |
641 | } |
642 | |
643 | QString QFileDialogOptions::labelText(QFileDialogOptions::DialogLabel label) const |
644 | { |
645 | return (unsigned(label) < unsigned(DialogLabelCount)) ? d->labels[label] : QString(); |
646 | } |
647 | |
648 | bool QFileDialogOptions::isLabelExplicitlySet(DialogLabel label) |
649 | { |
650 | return unsigned(label) < unsigned(DialogLabelCount) && !d->labels[label].isEmpty(); |
651 | } |
652 | |
653 | QUrl QFileDialogOptions::initialDirectory() const |
654 | { |
655 | return d->initialDirectory; |
656 | } |
657 | |
658 | void QFileDialogOptions::setInitialDirectory(const QUrl &directory) |
659 | { |
660 | d->initialDirectory = directory; |
661 | } |
662 | |
663 | QString QFileDialogOptions::initiallySelectedMimeTypeFilter() const |
664 | { |
665 | return d->initiallySelectedMimeTypeFilter; |
666 | } |
667 | |
668 | void QFileDialogOptions::setInitiallySelectedMimeTypeFilter(const QString &filter) |
669 | { |
670 | d->initiallySelectedMimeTypeFilter = filter; |
671 | } |
672 | |
673 | QString QFileDialogOptions::initiallySelectedNameFilter() const |
674 | { |
675 | return d->initiallySelectedNameFilter; |
676 | } |
677 | |
678 | void QFileDialogOptions::setInitiallySelectedNameFilter(const QString &filter) |
679 | { |
680 | d->initiallySelectedNameFilter = filter; |
681 | } |
682 | |
683 | QList<QUrl> QFileDialogOptions::initiallySelectedFiles() const |
684 | { |
685 | return d->initiallySelectedFiles; |
686 | } |
687 | |
688 | void QFileDialogOptions::setInitiallySelectedFiles(const QList<QUrl> &files) |
689 | { |
690 | d->initiallySelectedFiles = files; |
691 | } |
692 | |
693 | // Schemes supported by the application |
694 | void QFileDialogOptions::setSupportedSchemes(const QStringList &schemes) |
695 | { |
696 | d->supportedSchemes = schemes; |
697 | } |
698 | |
699 | QStringList QFileDialogOptions::supportedSchemes() const |
700 | { |
701 | return d->supportedSchemes; |
702 | } |
703 | |
704 | void QPlatformFileDialogHelper::selectMimeTypeFilter(const QString &filter) |
705 | { |
706 | Q_UNUSED(filter); |
707 | } |
708 | |
709 | QString 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. |
715 | bool 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 | */ |
729 | const QSharedPointer<QFileDialogOptions> &QPlatformFileDialogHelper::options() const |
730 | { |
731 | return m_options; |
732 | } |
733 | |
734 | void QPlatformFileDialogHelper::setOptions(const QSharedPointer<QFileDialogOptions> &options) |
735 | { |
736 | m_options = options; |
737 | } |
738 | |
739 | const char QPlatformFileDialogHelper::filterRegExp[] = |
740 | "^(.*)\\(([a-zA-Z0-9_.,*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"; |
741 | |
742 | // Makes a list of filters from a normal filter string "Image Files (*.png *.jpg)" |
743 | QStringList 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 | |
761 | class QMessageDialogOptionsPrivate : public QSharedData |
762 | { |
763 | public: |
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 | int defaultButtonId = 0; |
782 | int escapeButtonId = 0; |
783 | QMessageDialogOptions::Options options; |
784 | }; |
785 | |
786 | QMessageDialogOptions::QMessageDialogOptions(QMessageDialogOptionsPrivate *dd) |
787 | : d(dd) |
788 | { |
789 | } |
790 | |
791 | QMessageDialogOptions::~QMessageDialogOptions() |
792 | { |
793 | } |
794 | |
795 | namespace { |
796 | struct MessageDialogCombined : QMessageDialogOptionsPrivate, QMessageDialogOptions |
797 | { |
798 | MessageDialogCombined() : QMessageDialogOptionsPrivate(), QMessageDialogOptions(this) {} |
799 | MessageDialogCombined(const MessageDialogCombined &other) |
800 | : QMessageDialogOptionsPrivate(other), QMessageDialogOptions(this) {} |
801 | }; |
802 | } |
803 | |
804 | // static |
805 | QSharedPointer<QMessageDialogOptions> QMessageDialogOptions::create() |
806 | { |
807 | return QSharedPointer<MessageDialogCombined>::create(); |
808 | } |
809 | |
810 | QSharedPointer<QMessageDialogOptions> QMessageDialogOptions::clone() const |
811 | { |
812 | return QSharedPointer<MessageDialogCombined>::create(arguments: *static_cast<const MessageDialogCombined*>(this)); |
813 | } |
814 | |
815 | QString QMessageDialogOptions::windowTitle() const |
816 | { |
817 | return d->windowTitle; |
818 | } |
819 | |
820 | void QMessageDialogOptions::setWindowTitle(const QString &title) |
821 | { |
822 | d->windowTitle = title; |
823 | } |
824 | |
825 | QMessageDialogOptions::StandardIcon QMessageDialogOptions::standardIcon() const |
826 | { |
827 | return d->icon; |
828 | } |
829 | |
830 | void QMessageDialogOptions::setStandardIcon(StandardIcon icon) |
831 | { |
832 | d->icon = icon; |
833 | } |
834 | |
835 | void QMessageDialogOptions::setIconPixmap(const QPixmap &pixmap) |
836 | { |
837 | d->iconPixmap = pixmap; |
838 | } |
839 | |
840 | QPixmap QMessageDialogOptions::iconPixmap() const |
841 | { |
842 | return d->iconPixmap; |
843 | } |
844 | |
845 | QString QMessageDialogOptions::text() const |
846 | { |
847 | return d->text; |
848 | } |
849 | |
850 | void QMessageDialogOptions::setText(const QString &text) |
851 | { |
852 | d->text = text; |
853 | } |
854 | |
855 | QString QMessageDialogOptions::informativeText() const |
856 | { |
857 | return d->informativeText; |
858 | } |
859 | |
860 | void QMessageDialogOptions::setInformativeText(const QString &informativeText) |
861 | { |
862 | d->informativeText = informativeText; |
863 | } |
864 | |
865 | QString QMessageDialogOptions::detailedText() const |
866 | { |
867 | return d->detailedText; |
868 | } |
869 | |
870 | void QMessageDialogOptions::setDetailedText(const QString &detailedText) |
871 | { |
872 | d->detailedText = detailedText; |
873 | } |
874 | |
875 | void QMessageDialogOptions::setStandardButtons(QPlatformDialogHelper::StandardButtons buttons) |
876 | { |
877 | d->buttons = buttons; |
878 | } |
879 | |
880 | QPlatformDialogHelper::StandardButtons QMessageDialogOptions::standardButtons() const |
881 | { |
882 | return d->buttons; |
883 | } |
884 | |
885 | int QMessageDialogOptions::addButton(const QString &label, QPlatformDialogHelper::ButtonRole role, |
886 | void *buttonImpl, int buttonId) |
887 | { |
888 | const CustomButton b(buttonId ? buttonId : d->nextCustomButtonId++, label, role, buttonImpl); |
889 | d->customButtons.append(t: b); |
890 | return b.id; |
891 | } |
892 | |
893 | static inline bool operator==(const QMessageDialogOptions::CustomButton &a, |
894 | const QMessageDialogOptions::CustomButton &b) { |
895 | return a.id == b.id; |
896 | } |
897 | |
898 | void QMessageDialogOptions::removeButton(int id) |
899 | { |
900 | d->customButtons.removeOne(t: CustomButton(id)); |
901 | } |
902 | |
903 | const QList<QMessageDialogOptions::CustomButton> &QMessageDialogOptions::customButtons() |
904 | { |
905 | return d->customButtons; |
906 | } |
907 | |
908 | void QMessageDialogOptions::clearCustomButtons() |
909 | { |
910 | d->customButtons.clear(); |
911 | } |
912 | |
913 | const QMessageDialogOptions::CustomButton *QMessageDialogOptions::customButton(int id) |
914 | { |
915 | const int i = int(d->customButtons.indexOf(t: CustomButton(id))); |
916 | return (i < 0 ? nullptr : &d->customButtons.at(i)); |
917 | } |
918 | |
919 | void QMessageDialogOptions::setCheckBox(const QString &label, Qt::CheckState state) |
920 | { |
921 | d->checkBoxLabel = label; |
922 | d->checkBoxState = state; |
923 | } |
924 | |
925 | QString QMessageDialogOptions::checkBoxLabel() const |
926 | { |
927 | return d->checkBoxLabel; |
928 | } |
929 | |
930 | Qt::CheckState QMessageDialogOptions::checkBoxState() const |
931 | { |
932 | return d->checkBoxState; |
933 | } |
934 | |
935 | void QMessageDialogOptions::setDefaultButton(int id) |
936 | { |
937 | d->defaultButtonId = id; |
938 | } |
939 | |
940 | int QMessageDialogOptions::defaultButton() const |
941 | { |
942 | return d->defaultButtonId; |
943 | } |
944 | |
945 | void QMessageDialogOptions::setEscapeButton(int id) |
946 | { |
947 | d->escapeButtonId = id; |
948 | } |
949 | |
950 | int QMessageDialogOptions::escapeButton() const |
951 | { |
952 | return d->escapeButtonId; |
953 | } |
954 | |
955 | void QMessageDialogOptions::setOption(QMessageDialogOptions::Option option, bool on) |
956 | { |
957 | if (!(d->options & option) != !on) |
958 | setOptions(d->options ^ option); |
959 | } |
960 | |
961 | bool QMessageDialogOptions::testOption(QMessageDialogOptions::Option option) const |
962 | { |
963 | return d->options & option; |
964 | } |
965 | |
966 | void QMessageDialogOptions::setOptions(QMessageDialogOptions::Options options) |
967 | { |
968 | if (options != d->options) |
969 | d->options = options; |
970 | } |
971 | |
972 | QMessageDialogOptions::Options QMessageDialogOptions::options() const |
973 | { |
974 | return d->options; |
975 | } |
976 | |
977 | |
978 | QPlatformDialogHelper::ButtonRole QPlatformDialogHelper::buttonRole(QPlatformDialogHelper::StandardButton button) |
979 | { |
980 | switch (button) { |
981 | case Ok: |
982 | case Save: |
983 | case Open: |
984 | case SaveAll: |
985 | case Retry: |
986 | case Ignore: |
987 | return AcceptRole; |
988 | |
989 | case Cancel: |
990 | case Close: |
991 | case Abort: |
992 | return RejectRole; |
993 | |
994 | case Discard: |
995 | return DestructiveRole; |
996 | |
997 | case Help: |
998 | return HelpRole; |
999 | |
1000 | case Apply: |
1001 | return ApplyRole; |
1002 | |
1003 | case Yes: |
1004 | case YesToAll: |
1005 | return YesRole; |
1006 | |
1007 | case No: |
1008 | case NoToAll: |
1009 | return NoRole; |
1010 | |
1011 | case RestoreDefaults: |
1012 | case Reset: |
1013 | return ResetRole; |
1014 | |
1015 | default: |
1016 | break; |
1017 | } |
1018 | return InvalidRole; |
1019 | } |
1020 | |
1021 | const int *QPlatformDialogHelper::buttonLayout(Qt::Orientation orientation, ButtonLayout policy) |
1022 | { |
1023 | if (policy == UnknownLayout) { |
1024 | #if defined (Q_OS_MACOS) |
1025 | policy = MacLayout; |
1026 | #elif defined (Q_OS_LINUX) || defined (Q_OS_UNIX) |
1027 | policy = KdeLayout; |
1028 | #elif defined (Q_OS_ANDROID) |
1029 | policy = AndroidLayout; |
1030 | #else |
1031 | policy = WinLayout; |
1032 | #endif |
1033 | } |
1034 | return buttonRoleLayouts[orientation == Qt::Vertical][policy]; |
1035 | } |
1036 | |
1037 | /*! |
1038 | \class QPlatformMessageDialogHelper |
1039 | \since 5.0 |
1040 | \internal |
1041 | \ingroup qpa |
1042 | |
1043 | \brief The QPlatformMessageDialogHelper class allows for platform-specific customization of Message dialogs. |
1044 | |
1045 | */ |
1046 | const QSharedPointer<QMessageDialogOptions> &QPlatformMessageDialogHelper::options() const |
1047 | { |
1048 | return m_options; |
1049 | } |
1050 | |
1051 | void QPlatformMessageDialogHelper::setOptions(const QSharedPointer<QMessageDialogOptions> &options) |
1052 | { |
1053 | m_options = options; |
1054 | } |
1055 | |
1056 | QT_END_NAMESPACE |
1057 | |
1058 | #include "moc_qplatformdialoghelper.cpp" |
1059 |
Definitions
- buttonRoleLayouts
- QPlatformDialogHelper
- ~QPlatformDialogHelper
- styleHint
- defaultStyleHint
- QFontDialogOptionsPrivate
- QFontDialogOptionsPrivate
- QFontDialogOptions
- ~QFontDialogOptions
- FontDialogCombined
- FontDialogCombined
- FontDialogCombined
- create
- clone
- windowTitle
- setWindowTitle
- setOption
- testOption
- setOptions
- options
- options
- setOptions
- QColorDialogStaticData
- QColorDialogStaticData
- readSettings
- writeSettings
- qColorDialogStaticData
- QColorDialogOptionsPrivate
- QColorDialogOptionsPrivate
- ~QColorDialogOptionsPrivate
- QColorDialogOptions
- ~QColorDialogOptions
- ColorDialogCombined
- ColorDialogCombined
- ColorDialogCombined
- create
- clone
- windowTitle
- setWindowTitle
- setOption
- testOption
- setOptions
- options
- customColorCount
- customColor
- customColors
- setCustomColor
- standardColors
- standardColor
- setStandardColor
- options
- setOptions
- QFileDialogOptionsPrivate
- QFileDialogOptions
- ~QFileDialogOptions
- FileDialogCombined
- FileDialogCombined
- FileDialogCombined
- create
- clone
- windowTitle
- setWindowTitle
- setOption
- testOption
- setOptions
- options
- filter
- setFilter
- setViewMode
- viewMode
- setFileMode
- fileMode
- setAcceptMode
- acceptMode
- setSidebarUrls
- sidebarUrls
- useDefaultNameFilters
- setUseDefaultNameFilters
- setNameFilters
- nameFilters
- defaultNameFilterString
- setMimeTypeFilters
- mimeTypeFilters
- setDefaultSuffix
- defaultSuffix
- setHistory
- history
- setLabelText
- labelText
- isLabelExplicitlySet
- initialDirectory
- setInitialDirectory
- initiallySelectedMimeTypeFilter
- setInitiallySelectedMimeTypeFilter
- initiallySelectedNameFilter
- setInitiallySelectedNameFilter
- initiallySelectedFiles
- setInitiallySelectedFiles
- setSupportedSchemes
- supportedSchemes
- selectMimeTypeFilter
- selectedMimeTypeFilter
- isSupportedUrl
- options
- setOptions
- filterRegExp
- cleanFilterList
- QMessageDialogOptionsPrivate
- QMessageDialogOptionsPrivate
- QMessageDialogOptions
- ~QMessageDialogOptions
- MessageDialogCombined
- MessageDialogCombined
- MessageDialogCombined
- create
- clone
- windowTitle
- setWindowTitle
- standardIcon
- setStandardIcon
- setIconPixmap
- iconPixmap
- text
- setText
- informativeText
- setInformativeText
- detailedText
- setDetailedText
- setStandardButtons
- standardButtons
- addButton
- operator==
- removeButton
- customButtons
- clearCustomButtons
- customButton
- setCheckBox
- checkBoxLabel
- checkBoxState
- setDefaultButton
- defaultButton
- setEscapeButton
- escapeButton
- setOption
- testOption
- setOptions
- options
- buttonRole
- buttonLayout
- options
Learn Advanced QML with KDAB
Find out more