1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the examples of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:BSD$
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** BSD License Usage
18** Alternatively, you may use this file under the terms of the BSD license
19** as follows:
20**
21** "Redistribution and use in source and binary forms, with or without
22** modification, are permitted provided that the following conditions are
23** met:
24** * Redistributions of source code must retain the above copyright
25** notice, this list of conditions and the following disclaimer.
26** * Redistributions in binary form must reproduce the above copyright
27** notice, this list of conditions and the following disclaimer in
28** the documentation and/or other materials provided with the
29** distribution.
30** * Neither the name of The Qt Company Ltd nor the names of its
31** contributors may be used to endorse or promote products derived
32** from this software without specific prior written permission.
33**
34**
35** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46**
47** $QT_END_LICENSE$
48**
49****************************************************************************/
50
51#include <QtWidgets>
52
53#include "dialog.h"
54
55#define MESSAGE \
56 Dialog::tr("<p>Message boxes have a caption, a text, " \
57 "and any number of buttons, each with standard or custom texts." \
58 "<p>Click a button to close the message box. Pressing the Esc button " \
59 "will activate the detected escape button (if any).")
60#define MESSAGE_DETAILS \
61 Dialog::tr("If a message box has detailed text, the user can reveal it " \
62 "by pressing the Show Details... button.")
63
64
65class DialogOptionsWidget : public QGroupBox
66{
67public:
68 explicit DialogOptionsWidget(QWidget *parent = nullptr);
69
70 void addCheckBox(const QString &text, int value);
71 void addSpacer();
72 int value() const;
73
74private:
75 typedef QPair<QCheckBox *, int> CheckBoxEntry;
76 QVBoxLayout *layout;
77 QList<CheckBoxEntry> checkBoxEntries;
78};
79
80DialogOptionsWidget::DialogOptionsWidget(QWidget *parent) :
81 QGroupBox(parent) , layout(new QVBoxLayout)
82{
83 setTitle(Dialog::tr("Options"));
84 setLayout(layout);
85}
86
87void DialogOptionsWidget::addCheckBox(const QString &text, int value)
88{
89 QCheckBox *checkBox = new QCheckBox(text);
90 layout->addWidget(checkBox);
91 checkBoxEntries.append(CheckBoxEntry(checkBox, value));
92}
93
94void DialogOptionsWidget::addSpacer()
95{
96 layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
97}
98
99int DialogOptionsWidget::value() const
100{
101 int result = 0;
102 for (const CheckBoxEntry &checkboxEntry : qAsConst(checkBoxEntries)) {
103 if (checkboxEntry.first->isChecked())
104 result |= checkboxEntry.second;
105 }
106 return result;
107}
108
109Dialog::Dialog(QWidget *parent)
110 : QWidget(parent)
111{
112 QVBoxLayout *verticalLayout;
113 if (QGuiApplication::styleHints()->showIsFullScreen() || QGuiApplication::styleHints()->showIsMaximized()) {
114 QHBoxLayout *horizontalLayout = new QHBoxLayout(this);
115 QGroupBox *groupBox = new QGroupBox(QGuiApplication::applicationDisplayName(), this);
116 horizontalLayout->addWidget(groupBox);
117 verticalLayout = new QVBoxLayout(groupBox);
118 } else {
119 verticalLayout = new QVBoxLayout(this);
120 }
121
122 QToolBox *toolbox = new QToolBox;
123 verticalLayout->addWidget(toolbox);
124
125 errorMessageDialog = new QErrorMessage(this);
126
127 int frameStyle = QFrame::Sunken | QFrame::Panel;
128
129 integerLabel = new QLabel;
130 integerLabel->setFrameStyle(frameStyle);
131 QPushButton *integerButton =
132 new QPushButton(tr("QInputDialog::get&Int()"));
133
134 doubleLabel = new QLabel;
135 doubleLabel->setFrameStyle(frameStyle);
136 QPushButton *doubleButton =
137 new QPushButton(tr("QInputDialog::get&Double()"));
138
139 itemLabel = new QLabel;
140 itemLabel->setFrameStyle(frameStyle);
141 QPushButton *itemButton = new QPushButton(tr("QInputDialog::getIte&m()"));
142
143 textLabel = new QLabel;
144 textLabel->setFrameStyle(frameStyle);
145 QPushButton *textButton = new QPushButton(tr("QInputDialog::get&Text()"));
146
147 multiLineTextLabel = new QLabel;
148 multiLineTextLabel->setFrameStyle(frameStyle);
149 QPushButton *multiLineTextButton = new QPushButton(tr("QInputDialog::get&MultiLineText()"));
150
151 colorLabel = new QLabel;
152 colorLabel->setFrameStyle(frameStyle);
153 QPushButton *colorButton = new QPushButton(tr("QColorDialog::get&Color()"));
154
155 fontLabel = new QLabel;
156 fontLabel->setFrameStyle(frameStyle);
157 QPushButton *fontButton = new QPushButton(tr("QFontDialog::get&Font()"));
158
159 directoryLabel = new QLabel;
160 directoryLabel->setFrameStyle(frameStyle);
161 QPushButton *directoryButton =
162 new QPushButton(tr("QFileDialog::getE&xistingDirectory()"));
163
164 openFileNameLabel = new QLabel;
165 openFileNameLabel->setFrameStyle(frameStyle);
166 QPushButton *openFileNameButton =
167 new QPushButton(tr("QFileDialog::get&OpenFileName()"));
168
169 openFileNamesLabel = new QLabel;
170 openFileNamesLabel->setFrameStyle(frameStyle);
171 QPushButton *openFileNamesButton =
172 new QPushButton(tr("QFileDialog::&getOpenFileNames()"));
173
174 saveFileNameLabel = new QLabel;
175 saveFileNameLabel->setFrameStyle(frameStyle);
176 QPushButton *saveFileNameButton =
177 new QPushButton(tr("QFileDialog::get&SaveFileName()"));
178
179 criticalLabel = new QLabel;
180 criticalLabel->setFrameStyle(frameStyle);
181 QPushButton *criticalButton =
182 new QPushButton(tr("QMessageBox::critica&l()"));
183
184 informationLabel = new QLabel;
185 informationLabel->setFrameStyle(frameStyle);
186 QPushButton *informationButton =
187 new QPushButton(tr("QMessageBox::i&nformation()"));
188
189 questionLabel = new QLabel;
190 questionLabel->setFrameStyle(frameStyle);
191 QPushButton *questionButton =
192 new QPushButton(tr("QMessageBox::&question()"));
193
194 warningLabel = new QLabel;
195 warningLabel->setFrameStyle(frameStyle);
196 QPushButton *warningButton = new QPushButton(tr("QMessageBox::&warning()"));
197
198 errorLabel = new QLabel;
199 errorLabel->setFrameStyle(frameStyle);
200 QPushButton *errorButton =
201 new QPushButton(tr("QErrorMessage::showM&essage()"));
202
203 connect(integerButton, &QAbstractButton::clicked, this, &Dialog::setInteger);
204 connect(doubleButton, &QAbstractButton::clicked, this, &Dialog::setDouble);
205 connect(itemButton, &QAbstractButton::clicked, this, &Dialog::setItem);
206 connect(textButton, &QAbstractButton::clicked, this, &Dialog::setText);
207 connect(multiLineTextButton, &QAbstractButton::clicked, this, &Dialog::setMultiLineText);
208 connect(colorButton, &QAbstractButton::clicked, this, &Dialog::setColor);
209 connect(fontButton, &QAbstractButton::clicked, this, &Dialog::setFont);
210 connect(directoryButton, &QAbstractButton::clicked,
211 this, &Dialog::setExistingDirectory);
212 connect(openFileNameButton, &QAbstractButton::clicked,
213 this, &Dialog::setOpenFileName);
214 connect(openFileNamesButton, &QAbstractButton::clicked,
215 this, &Dialog::setOpenFileNames);
216 connect(saveFileNameButton, &QAbstractButton::clicked,
217 this, &Dialog::setSaveFileName);
218 connect(criticalButton, &QAbstractButton::clicked, this, &Dialog::criticalMessage);
219 connect(informationButton, &QAbstractButton::clicked,
220 this, &Dialog::informationMessage);
221 connect(questionButton, &QAbstractButton::clicked, this, &Dialog::questionMessage);
222 connect(warningButton, &QAbstractButton::clicked, this, &Dialog::warningMessage);
223 connect(errorButton, &QAbstractButton::clicked, this, &Dialog::errorMessage);
224
225 QWidget *page = new QWidget;
226 QGridLayout *layout = new QGridLayout(page);
227 layout->setColumnStretch(1, 1);
228 layout->setColumnMinimumWidth(1, 250);
229 layout->addWidget(integerButton, 0, 0);
230 layout->addWidget(integerLabel, 0, 1);
231 layout->addWidget(doubleButton, 1, 0);
232 layout->addWidget(doubleLabel, 1, 1);
233 layout->addWidget(itemButton, 2, 0);
234 layout->addWidget(itemLabel, 2, 1);
235 layout->addWidget(textButton, 3, 0);
236 layout->addWidget(textLabel, 3, 1);
237 layout->addWidget(multiLineTextButton, 4, 0);
238 layout->addWidget(multiLineTextLabel, 4, 1);
239 layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding), 5, 0);
240 toolbox->addItem(page, tr("Input Dialogs"));
241
242 const QString doNotUseNativeDialog = tr("Do not use native dialog");
243
244 page = new QWidget;
245 layout = new QGridLayout(page);
246 layout->setColumnStretch(1, 1);
247 layout->addWidget(colorButton, 0, 0);
248 layout->addWidget(colorLabel, 0, 1);
249 colorDialogOptionsWidget = new DialogOptionsWidget;
250 colorDialogOptionsWidget->addCheckBox(doNotUseNativeDialog, QColorDialog::DontUseNativeDialog);
251 colorDialogOptionsWidget->addCheckBox(tr("Show alpha channel") , QColorDialog::ShowAlphaChannel);
252 colorDialogOptionsWidget->addCheckBox(tr("No buttons") , QColorDialog::NoButtons);
253 layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding), 1, 0);
254 layout->addWidget(colorDialogOptionsWidget, 2, 0, 1 ,2);
255
256 toolbox->addItem(page, tr("Color Dialog"));
257
258 page = new QWidget;
259 layout = new QGridLayout(page);
260 layout->setColumnStretch(1, 1);
261 layout->addWidget(fontButton, 0, 0);
262 layout->addWidget(fontLabel, 0, 1);
263 fontDialogOptionsWidget = new DialogOptionsWidget;
264 fontDialogOptionsWidget->addCheckBox(doNotUseNativeDialog, QFontDialog::DontUseNativeDialog);
265 fontDialogOptionsWidget->addCheckBox(tr("Show scalable fonts"), QFontDialog::ScalableFonts);
266 fontDialogOptionsWidget->addCheckBox(tr("Show non scalable fonts"), QFontDialog::NonScalableFonts);
267 fontDialogOptionsWidget->addCheckBox(tr("Show monospaced fonts"), QFontDialog::MonospacedFonts);
268 fontDialogOptionsWidget->addCheckBox(tr("Show proportional fonts"), QFontDialog::ProportionalFonts);
269 fontDialogOptionsWidget->addCheckBox(tr("No buttons") , QFontDialog::NoButtons);
270 layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding), 1, 0);
271 layout->addWidget(fontDialogOptionsWidget, 2, 0, 1 ,2);
272 toolbox->addItem(page, tr("Font Dialog"));
273
274 page = new QWidget;
275 layout = new QGridLayout(page);
276 layout->setColumnStretch(1, 1);
277 layout->addWidget(directoryButton, 0, 0);
278 layout->addWidget(directoryLabel, 0, 1);
279 layout->addWidget(openFileNameButton, 1, 0);
280 layout->addWidget(openFileNameLabel, 1, 1);
281 layout->addWidget(openFileNamesButton, 2, 0);
282 layout->addWidget(openFileNamesLabel, 2, 1);
283 layout->addWidget(saveFileNameButton, 3, 0);
284 layout->addWidget(saveFileNameLabel, 3, 1);
285 fileDialogOptionsWidget = new DialogOptionsWidget;
286 fileDialogOptionsWidget->addCheckBox(doNotUseNativeDialog, QFileDialog::DontUseNativeDialog);
287 fileDialogOptionsWidget->addCheckBox(tr("Show directories only"), QFileDialog::ShowDirsOnly);
288 fileDialogOptionsWidget->addCheckBox(tr("Do not resolve symlinks"), QFileDialog::DontResolveSymlinks);
289 fileDialogOptionsWidget->addCheckBox(tr("Do not confirm overwrite"), QFileDialog::DontConfirmOverwrite);
290 fileDialogOptionsWidget->addCheckBox(tr("Readonly"), QFileDialog::ReadOnly);
291 fileDialogOptionsWidget->addCheckBox(tr("Hide name filter details"), QFileDialog::HideNameFilterDetails);
292 fileDialogOptionsWidget->addCheckBox(tr("Do not use custom directory icons (Windows)"), QFileDialog::DontUseCustomDirectoryIcons);
293 layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding), 4, 0);
294 layout->addWidget(fileDialogOptionsWidget, 5, 0, 1 ,2);
295 toolbox->addItem(page, tr("File Dialogs"));
296
297 page = new QWidget;
298 layout = new QGridLayout(page);
299 layout->setColumnStretch(1, 1);
300 layout->addWidget(criticalButton, 0, 0);
301 layout->addWidget(criticalLabel, 0, 1);
302 layout->addWidget(informationButton, 1, 0);
303 layout->addWidget(informationLabel, 1, 1);
304 layout->addWidget(questionButton, 2, 0);
305 layout->addWidget(questionLabel, 2, 1);
306 layout->addWidget(warningButton, 3, 0);
307 layout->addWidget(warningLabel, 3, 1);
308 layout->addWidget(errorButton, 4, 0);
309 layout->addWidget(errorLabel, 4, 1);
310 layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding), 5, 0);
311 toolbox->addItem(page, tr("Message Boxes"));
312
313 setWindowTitle(QGuiApplication::applicationDisplayName());
314}
315
316void Dialog::setInteger()
317{
318//! [0]
319 bool ok;
320 int i = QInputDialog::getInt(this, tr("QInputDialog::getInt()"),
321 tr("Percentage:"), 25, 0, 100, 1, &ok);
322 if (ok)
323 integerLabel->setText(tr("%1%").arg(i));
324//! [0]
325}
326
327void Dialog::setDouble()
328{
329//! [1]
330 bool ok;
331 double d = QInputDialog::getDouble(this, tr("QInputDialog::getDouble()"),
332 tr("Amount:"), 37.56, -10000, 10000, 2, &ok,
333 Qt::WindowFlags(), 1);
334 if (ok)
335 doubleLabel->setText(QString("$%1").arg(d));
336//! [1]
337}
338
339void Dialog::setItem()
340{
341//! [2]
342 QStringList items;
343 items << tr("Spring") << tr("Summer") << tr("Fall") << tr("Winter");
344
345 bool ok;
346 QString item = QInputDialog::getItem(this, tr("QInputDialog::getItem()"),
347 tr("Season:"), items, 0, false, &ok);
348 if (ok && !item.isEmpty())
349 itemLabel->setText(item);
350//! [2]
351}
352
353void Dialog::setText()
354{
355//! [3]
356 bool ok;
357 QString text = QInputDialog::getText(this, tr("QInputDialog::getText()"),
358 tr("User name:"), QLineEdit::Normal,
359 QDir::home().dirName(), &ok);
360 if (ok && !text.isEmpty())
361 textLabel->setText(text);
362//! [3]
363}
364
365void Dialog::setMultiLineText()
366{
367//! [4]
368 bool ok;
369 QString text = QInputDialog::getMultiLineText(this, tr("QInputDialog::getMultiLineText()"),
370 tr("Address:"), "John Doe\nFreedom Street", &ok);
371 if (ok && !text.isEmpty())
372 multiLineTextLabel->setText(text);
373//! [4]
374}
375
376void Dialog::setColor()
377{
378 const QColorDialog::ColorDialogOptions options = QFlag(colorDialogOptionsWidget->value());
379 const QColor color = QColorDialog::getColor(Qt::green, this, "Select Color", options);
380
381 if (color.isValid()) {
382 colorLabel->setText(color.name());
383 colorLabel->setPalette(QPalette(color));
384 colorLabel->setAutoFillBackground(true);
385 }
386}
387
388void Dialog::setFont()
389{
390 const QFontDialog::FontDialogOptions options = QFlag(fontDialogOptionsWidget->value());
391 bool ok;
392 QFont font = QFontDialog::getFont(&ok, QFont(fontLabel->text()), this, "Select Font", options);
393 if (ok) {
394 fontLabel->setText(font.key());
395 fontLabel->setFont(font);
396 }
397}
398
399void Dialog::setExistingDirectory()
400{
401 QFileDialog::Options options = QFlag(fileDialogOptionsWidget->value());
402 options |= QFileDialog::DontResolveSymlinks | QFileDialog::ShowDirsOnly;
403 QString directory = QFileDialog::getExistingDirectory(this,
404 tr("QFileDialog::getExistingDirectory()"),
405 directoryLabel->text(),
406 options);
407 if (!directory.isEmpty())
408 directoryLabel->setText(directory);
409}
410
411void Dialog::setOpenFileName()
412{
413 const QFileDialog::Options options = QFlag(fileDialogOptionsWidget->value());
414 QString selectedFilter;
415 QString fileName = QFileDialog::getOpenFileName(this,
416 tr("QFileDialog::getOpenFileName()"),
417 openFileNameLabel->text(),
418 tr("All Files (*);;Text Files (*.txt)"),
419 &selectedFilter,
420 options);
421 if (!fileName.isEmpty())
422 openFileNameLabel->setText(fileName);
423}
424
425void Dialog::setOpenFileNames()
426{
427 const QFileDialog::Options options = QFlag(fileDialogOptionsWidget->value());
428 QString selectedFilter;
429 QStringList files = QFileDialog::getOpenFileNames(
430 this, tr("QFileDialog::getOpenFileNames()"),
431 openFilesPath,
432 tr("All Files (*);;Text Files (*.txt)"),
433 &selectedFilter,
434 options);
435 if (files.count()) {
436 openFilesPath = files[0];
437 openFileNamesLabel->setText(QString("[%1]").arg(files.join(", ")));
438 }
439}
440
441void Dialog::setSaveFileName()
442{
443 const QFileDialog::Options options = QFlag(fileDialogOptionsWidget->value());
444 QString selectedFilter;
445 QString fileName = QFileDialog::getSaveFileName(this,
446 tr("QFileDialog::getSaveFileName()"),
447 saveFileNameLabel->text(),
448 tr("All Files (*);;Text Files (*.txt)"),
449 &selectedFilter,
450 options);
451 if (!fileName.isEmpty())
452 saveFileNameLabel->setText(fileName);
453}
454
455void Dialog::criticalMessage()
456{
457 QMessageBox::StandardButton reply;
458 reply = QMessageBox::critical(this, tr("QMessageBox::critical()"),
459 MESSAGE,
460 QMessageBox::Abort | QMessageBox::Retry | QMessageBox::Ignore);
461 if (reply == QMessageBox::Abort)
462 criticalLabel->setText(tr("Abort"));
463 else if (reply == QMessageBox::Retry)
464 criticalLabel->setText(tr("Retry"));
465 else
466 criticalLabel->setText(tr("Ignore"));
467}
468
469void Dialog::informationMessage()
470{
471 QMessageBox::StandardButton reply;
472 reply = QMessageBox::information(this, tr("QMessageBox::information()"), MESSAGE);
473 if (reply == QMessageBox::Ok)
474 informationLabel->setText(tr("OK"));
475 else
476 informationLabel->setText(tr("Escape"));
477}
478
479void Dialog::questionMessage()
480{
481 QMessageBox::StandardButton reply;
482 reply = QMessageBox::question(this, tr("QMessageBox::question()"),
483 MESSAGE,
484 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
485 if (reply == QMessageBox::Yes)
486 questionLabel->setText(tr("Yes"));
487 else if (reply == QMessageBox::No)
488 questionLabel->setText(tr("No"));
489 else
490 questionLabel->setText(tr("Cancel"));
491}
492
493void Dialog::warningMessage()
494{
495 QMessageBox msgBox(QMessageBox::Warning, tr("QMessageBox::warning()"),
496 MESSAGE, { }, this);
497 msgBox.setDetailedText(MESSAGE_DETAILS);
498 msgBox.addButton(tr("Save &Again"), QMessageBox::AcceptRole);
499 msgBox.addButton(tr("&Continue"), QMessageBox::RejectRole);
500 if (msgBox.exec() == QMessageBox::AcceptRole)
501 warningLabel->setText(tr("Save Again"));
502 else
503 warningLabel->setText(tr("Continue"));
504
505}
506
507void Dialog::errorMessage()
508{
509 errorMessageDialog->showMessage(
510 tr("This dialog shows and remembers error messages. "
511 "If the checkbox is checked (as it is by default), "
512 "the shown message will be shown again, "
513 "but if the user unchecks the box the message "
514 "will not appear again if QErrorMessage::showMessage() "
515 "is called with the same message."));
516 errorLabel->setText(tr("If the box is unchecked, the message "
517 "won't appear again."));
518}
519