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 QtWidgets 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 "qinputdialog.h"
41
42#include "qapplication.h"
43#include "qcombobox.h"
44#include "qdialogbuttonbox.h"
45#include "qlabel.h"
46#include "qlayout.h"
47#include "qlineedit.h"
48#include "qplaintextedit.h"
49#include "qlistview.h"
50#include "qpushbutton.h"
51#include "qspinbox.h"
52#include "qstackedlayout.h"
53#include "qvalidator.h"
54#include "qevent.h"
55#include "qdialog_p.h"
56
57QT_USE_NAMESPACE
58
59enum CandidateSignal {
60 TextValueSelectedSignal,
61 IntValueSelectedSignal,
62 DoubleValueSelectedSignal,
63
64 NumCandidateSignals
65};
66
67static const char *candidateSignal(int which)
68{
69 switch (CandidateSignal(which)) {
70 case TextValueSelectedSignal: return SIGNAL(textValueSelected(QString));
71 case IntValueSelectedSignal: return SIGNAL(intValueSelected(int));
72 case DoubleValueSelectedSignal: return SIGNAL(doubleValueSelected(double));
73
74 case NumCandidateSignals:
75 break;
76 };
77 Q_UNREACHABLE();
78 return nullptr;
79}
80
81static const char *signalForMember(const char *member)
82{
83 QByteArray normalizedMember(QMetaObject::normalizedSignature(member));
84
85 for (int i = 0; i < NumCandidateSignals; ++i)
86 if (QMetaObject::checkConnectArgs(candidateSignal(i), normalizedMember))
87 return candidateSignal(i);
88
89 // otherwise, use fit-all accepted signal:
90 return SIGNAL(accepted());
91}
92
93QT_BEGIN_NAMESPACE
94
95/*
96 These internal classes add extra validation to QSpinBox and QDoubleSpinBox by emitting
97 textChanged(bool) after events that may potentially change the visible text. Return or
98 Enter key presses are not propagated if the visible text is invalid. Instead, the visible
99 text is modified to the last valid value.
100*/
101class QInputDialogSpinBox : public QSpinBox
102{
103 Q_OBJECT
104
105public:
106 QInputDialogSpinBox(QWidget *parent)
107 : QSpinBox(parent) {
108 connect(lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(notifyTextChanged()));
109 connect(this, SIGNAL(editingFinished()), this, SLOT(notifyTextChanged()));
110 }
111
112signals:
113 void textChanged(bool);
114
115private slots:
116 void notifyTextChanged() { emit textChanged(hasAcceptableInput()); }
117
118private:
119 void keyPressEvent(QKeyEvent *event) override {
120 if ((event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) && !hasAcceptableInput()) {
121#ifndef QT_NO_PROPERTIES
122 setProperty("value", property("value"));
123#endif
124 } else {
125 QSpinBox::keyPressEvent(event);
126 }
127 notifyTextChanged();
128 }
129
130 void mousePressEvent(QMouseEvent *event) override {
131 QSpinBox::mousePressEvent(event);
132 notifyTextChanged();
133 }
134};
135
136class QInputDialogDoubleSpinBox : public QDoubleSpinBox
137{
138 Q_OBJECT
139
140public:
141 QInputDialogDoubleSpinBox(QWidget *parent = nullptr)
142 : QDoubleSpinBox(parent) {
143 connect(lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(notifyTextChanged()));
144 connect(this, SIGNAL(editingFinished()), this, SLOT(notifyTextChanged()));
145 }
146
147signals:
148 void textChanged(bool);
149
150private slots:
151 void notifyTextChanged() { emit textChanged(hasAcceptableInput()); }
152
153private:
154 void keyPressEvent(QKeyEvent *event) override {
155 if ((event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) && !hasAcceptableInput()) {
156#ifndef QT_NO_PROPERTIES
157 setProperty("value", property("value"));
158#endif
159 } else {
160 QDoubleSpinBox::keyPressEvent(event);
161 }
162 notifyTextChanged();
163 }
164
165 void mousePressEvent(QMouseEvent *event) override {
166 QDoubleSpinBox::mousePressEvent(event);
167 notifyTextChanged();
168 }
169};
170
171class QInputDialogListView : public QListView
172{
173public:
174 QInputDialogListView(QWidget *parent = nullptr) : QListView(parent) {}
175 QVariant inputMethodQuery(Qt::InputMethodQuery query) const override
176 {
177 if (query == Qt::ImEnabled)
178 return false;
179 return QListView::inputMethodQuery(query);
180 }
181};
182
183class QInputDialogPrivate : public QDialogPrivate
184{
185 Q_DECLARE_PUBLIC(QInputDialog)
186
187public:
188 QInputDialogPrivate();
189
190 void ensureLayout();
191 void ensureLineEdit();
192 void ensurePlainTextEdit();
193 void ensureComboBox();
194 void ensureListView();
195 void ensureIntSpinBox();
196 void ensureDoubleSpinBox();
197 void ensureEnabledConnection(QAbstractSpinBox *spinBox);
198 void setInputWidget(QWidget *widget);
199 void chooseRightTextInputWidget();
200 void setComboBoxText(const QString &text);
201 void setListViewText(const QString &text);
202 QString listViewText() const;
203 void ensureLayout() const { const_cast<QInputDialogPrivate *>(this)->ensureLayout(); }
204 bool useComboBoxOrListView() const { return comboBox && comboBox->count() > 0; }
205 void _q_textChanged(const QString &text);
206 void _q_plainTextEditTextChanged();
207 void _q_currentRowChanged(const QModelIndex &newIndex, const QModelIndex &oldIndex);
208
209 mutable QLabel *label;
210 mutable QDialogButtonBox *buttonBox;
211 mutable QLineEdit *lineEdit;
212 mutable QPlainTextEdit *plainTextEdit;
213 mutable QSpinBox *intSpinBox;
214 mutable QDoubleSpinBox *doubleSpinBox;
215 mutable QComboBox *comboBox;
216 mutable QInputDialogListView *listView;
217 mutable QWidget *inputWidget;
218 mutable QVBoxLayout *mainLayout;
219 QInputDialog::InputDialogOptions opts;
220 QString textValue;
221 QPointer<QObject> receiverToDisconnectOnClose;
222 QByteArray memberToDisconnectOnClose;
223};
224
225QInputDialogPrivate::QInputDialogPrivate()
226 : label(nullptr), buttonBox(nullptr), lineEdit(nullptr), plainTextEdit(nullptr), intSpinBox(nullptr), doubleSpinBox(nullptr),
227 comboBox(nullptr), listView(nullptr), inputWidget(nullptr), mainLayout(nullptr)
228{
229}
230
231void QInputDialogPrivate::ensureLayout()
232{
233 Q_Q(QInputDialog);
234
235 if (mainLayout)
236 return;
237
238 if (!inputWidget) {
239 ensureLineEdit();
240 inputWidget = lineEdit;
241 }
242
243 if (!label)
244 label = new QLabel(QInputDialog::tr("Enter a value:"), q);
245#ifndef QT_NO_SHORTCUT
246 label->setBuddy(inputWidget);
247#endif
248 label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
249
250 buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, q);
251 QObject::connect(buttonBox, SIGNAL(accepted()), q, SLOT(accept()));
252 QObject::connect(buttonBox, SIGNAL(rejected()), q, SLOT(reject()));
253
254 mainLayout = new QVBoxLayout(q);
255 mainLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
256 mainLayout->addWidget(label);
257 mainLayout->addWidget(inputWidget);
258 mainLayout->addWidget(buttonBox);
259 ensureEnabledConnection(qobject_cast<QAbstractSpinBox *>(inputWidget));
260 inputWidget->show();
261}
262
263void QInputDialogPrivate::ensureLineEdit()
264{
265 Q_Q(QInputDialog);
266 if (!lineEdit) {
267 lineEdit = new QLineEdit(q);
268#ifndef QT_NO_IM
269 qt_widget_private(lineEdit)->inheritsInputMethodHints = 1;
270#endif
271 lineEdit->hide();
272 QObject::connect(lineEdit, SIGNAL(textChanged(QString)),
273 q, SLOT(_q_textChanged(QString)));
274 }
275}
276
277void QInputDialogPrivate::ensurePlainTextEdit()
278{
279 Q_Q(QInputDialog);
280 if (!plainTextEdit) {
281 plainTextEdit = new QPlainTextEdit(q);
282 plainTextEdit->setLineWrapMode(QPlainTextEdit::NoWrap);
283#ifndef QT_NO_IM
284 qt_widget_private(plainTextEdit)->inheritsInputMethodHints = 1;
285#endif
286 plainTextEdit->hide();
287 QObject::connect(plainTextEdit, SIGNAL(textChanged()),
288 q, SLOT(_q_plainTextEditTextChanged()));
289 }
290}
291
292void QInputDialogPrivate::ensureComboBox()
293{
294 Q_Q(QInputDialog);
295 if (!comboBox) {
296 comboBox = new QComboBox(q);
297#ifndef QT_NO_IM
298 qt_widget_private(comboBox)->inheritsInputMethodHints = 1;
299#endif
300 comboBox->hide();
301 QObject::connect(comboBox, SIGNAL(editTextChanged(QString)),
302 q, SLOT(_q_textChanged(QString)));
303 QObject::connect(comboBox, SIGNAL(currentTextChanged(QString)),
304 q, SLOT(_q_textChanged(QString)));
305 }
306}
307
308void QInputDialogPrivate::ensureListView()
309{
310 Q_Q(QInputDialog);
311 if (!listView) {
312 ensureComboBox();
313 listView = new QInputDialogListView(q);
314 listView->hide();
315 listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
316 listView->setSelectionMode(QAbstractItemView::SingleSelection);
317 listView->setModel(comboBox->model());
318 listView->setCurrentIndex(QModelIndex()); // ###
319 QObject::connect(listView->selectionModel(),
320 SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
321 q, SLOT(_q_currentRowChanged(QModelIndex,QModelIndex)));
322 }
323}
324
325void QInputDialogPrivate::ensureIntSpinBox()
326{
327 Q_Q(QInputDialog);
328 if (!intSpinBox) {
329 intSpinBox = new QInputDialogSpinBox(q);
330 intSpinBox->hide();
331 QObject::connect(intSpinBox, SIGNAL(valueChanged(int)),
332 q, SIGNAL(intValueChanged(int)));
333 }
334}
335
336void QInputDialogPrivate::ensureDoubleSpinBox()
337{
338 Q_Q(QInputDialog);
339 if (!doubleSpinBox) {
340 doubleSpinBox = new QInputDialogDoubleSpinBox(q);
341 doubleSpinBox->hide();
342 QObject::connect(doubleSpinBox, SIGNAL(valueChanged(double)),
343 q, SIGNAL(doubleValueChanged(double)));
344 }
345}
346
347void QInputDialogPrivate::ensureEnabledConnection(QAbstractSpinBox *spinBox)
348{
349 if (spinBox) {
350 QAbstractButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
351 QObject::connect(spinBox, SIGNAL(textChanged(bool)), okButton, SLOT(setEnabled(bool)), Qt::UniqueConnection);
352 }
353}
354
355void QInputDialogPrivate::setInputWidget(QWidget *widget)
356{
357 Q_ASSERT(widget);
358 if (inputWidget == widget)
359 return;
360
361 if (mainLayout) {
362 Q_ASSERT(inputWidget);
363 mainLayout->removeWidget(inputWidget);
364 inputWidget->hide();
365 mainLayout->insertWidget(1, widget);
366 widget->show();
367
368 // disconnect old input widget
369 QAbstractButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
370 if (QAbstractSpinBox *spinBox = qobject_cast<QAbstractSpinBox *>(inputWidget))
371 QObject::disconnect(spinBox, SIGNAL(textChanged(bool)), okButton, SLOT(setEnabled(bool)));
372
373 // connect new input widget and update enabled state of OK button
374 QAbstractSpinBox *spinBox = qobject_cast<QAbstractSpinBox *>(widget);
375 ensureEnabledConnection(spinBox);
376 okButton->setEnabled(!spinBox || spinBox->hasAcceptableInput());
377 }
378
379 inputWidget = widget;
380
381 // synchronize the text shown in the new text editor with the current
382 // textValue
383 if (widget == lineEdit) {
384 lineEdit->setText(textValue);
385 } else if (widget == plainTextEdit) {
386 plainTextEdit->setPlainText(textValue);
387 } else if (widget == comboBox) {
388 setComboBoxText(textValue);
389 } else if (widget == listView) {
390 setListViewText(textValue);
391 ensureLayout();
392 buttonBox->button(QDialogButtonBox::Ok)->setEnabled(listView->selectionModel()->hasSelection());
393 }
394}
395
396void QInputDialogPrivate::chooseRightTextInputWidget()
397{
398 QWidget *widget;
399
400 if (useComboBoxOrListView()) {
401 if ((opts & QInputDialog::UseListViewForComboBoxItems) && !comboBox->isEditable()) {
402 ensureListView();
403 widget = listView;
404 } else {
405 widget = comboBox;
406 }
407 } else if (opts & QInputDialog::UsePlainTextEditForTextInput) {
408 ensurePlainTextEdit();
409 widget = plainTextEdit;
410 } else {
411 ensureLineEdit();
412 widget = lineEdit;
413 }
414
415 setInputWidget(widget);
416
417 if (inputWidget == comboBox) {
418 _q_textChanged(comboBox->currentText());
419 } else if (inputWidget == listView) {
420 _q_textChanged(listViewText());
421 }
422}
423
424void QInputDialogPrivate::setComboBoxText(const QString &text)
425{
426 int index = comboBox->findText(text);
427 if (index != -1) {
428 comboBox->setCurrentIndex(index);
429 } else if (comboBox->isEditable()) {
430 comboBox->setEditText(text);
431 }
432}
433
434void QInputDialogPrivate::setListViewText(const QString &text)
435{
436 int row = comboBox->findText(text);
437 if (row != -1) {
438 QModelIndex index(comboBox->model()->index(row, 0));
439 listView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Clear
440 | QItemSelectionModel::SelectCurrent);
441 }
442}
443
444QString QInputDialogPrivate::listViewText() const
445{
446 if (listView->selectionModel()->hasSelection()) {
447 int row = listView->selectionModel()->selectedRows().value(0).row();
448 return comboBox->itemText(row);
449 } else {
450 return QString();
451 }
452}
453
454void QInputDialogPrivate::_q_textChanged(const QString &text)
455{
456 Q_Q(QInputDialog);
457 if (textValue != text) {
458 textValue = text;
459 emit q->textValueChanged(text);
460 }
461}
462
463void QInputDialogPrivate::_q_plainTextEditTextChanged()
464{
465 Q_Q(QInputDialog);
466 QString text = plainTextEdit->toPlainText();
467 if (textValue != text) {
468 textValue = text;
469 emit q->textValueChanged(text);
470 }
471}
472
473void QInputDialogPrivate::_q_currentRowChanged(const QModelIndex &newIndex,
474 const QModelIndex & /* oldIndex */)
475{
476 _q_textChanged(comboBox->model()->data(newIndex).toString());
477 buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
478}
479
480/*!
481 \class QInputDialog
482 \brief The QInputDialog class provides a simple convenience dialog to get a
483 single value from the user.
484 \ingroup standard-dialogs
485 \inmodule QtWidgets
486
487 The input value can be a string, a number or an item from a list. A label
488 must be set to tell the user what they should enter.
489
490 Five static convenience functions are provided: getText(), getMultiLineText(),
491 getInt(), getDouble(), and getItem(). All the functions can be used in a similar way,
492 for example:
493
494 \snippet dialogs/standarddialogs/dialog.cpp 3
495
496 The \c ok variable is set to true if the user clicks \uicontrol OK; otherwise, it
497 is set to false.
498
499 \image inputdialogs.png Input Dialogs
500
501 The \l{dialogs/standarddialogs}{Standard Dialogs} example shows how to use
502 QInputDialog as well as other built-in Qt dialogs.
503
504 \sa QMessageBox, {Standard Dialogs Example}
505*/
506
507/*!
508 \enum QInputDialog::InputMode
509 \since 4.5
510
511 This enum describes the different modes of input that can be selected for
512 the dialog.
513
514 \value TextInput Used to input text strings.
515 \value IntInput Used to input integers.
516 \value DoubleInput Used to input floating point numbers with double
517 precision accuracy.
518
519 \sa inputMode
520*/
521
522/*!
523 \since 4.5
524
525 Constructs a new input dialog with the given \a parent and window \a flags.
526*/
527QInputDialog::QInputDialog(QWidget *parent, Qt::WindowFlags flags)
528 : QDialog(*new QInputDialogPrivate, parent, flags)
529{
530}
531
532/*!
533 \since 4.5
534
535 Destroys the input dialog.
536*/
537QInputDialog::~QInputDialog()
538{
539}
540
541/*!
542 \since 4.5
543
544 \property QInputDialog::inputMode
545
546 \brief the mode used for input
547
548 This property helps determine which widget is used for entering input into
549 the dialog.
550*/
551void QInputDialog::setInputMode(InputMode mode)
552{
553 Q_D(QInputDialog);
554
555 QWidget *widget;
556
557 /*
558 Warning: Some functions in QInputDialog rely on implementation details
559 of the code below. Look for the comments that accompany the calls to
560 setInputMode() throughout this file before you change the code below.
561 */
562
563 switch (mode) {
564 case IntInput:
565 d->ensureIntSpinBox();
566 widget = d->intSpinBox;
567 break;
568 case DoubleInput:
569 d->ensureDoubleSpinBox();
570 widget = d->doubleSpinBox;
571 break;
572 default:
573 Q_ASSERT(mode == TextInput);
574 d->chooseRightTextInputWidget();
575 return;
576 }
577
578 d->setInputWidget(widget);
579}
580
581QInputDialog::InputMode QInputDialog::inputMode() const
582{
583 Q_D(const QInputDialog);
584
585 if (d->inputWidget) {
586 if (d->inputWidget == d->intSpinBox) {
587 return IntInput;
588 } else if (d->inputWidget == d->doubleSpinBox) {
589 return DoubleInput;
590 }
591 }
592
593 return TextInput;
594}
595
596/*!
597 \since 4.5
598
599 \property QInputDialog::labelText
600
601 \brief the label's text which describes what needs to be input
602*/
603void QInputDialog::setLabelText(const QString &text)
604{
605 Q_D(QInputDialog);
606 if (!d->label) {
607 d->label = new QLabel(text, this);
608 } else {
609 d->label->setText(text);
610 }
611}
612
613QString QInputDialog::labelText() const
614{
615 Q_D(const QInputDialog);
616 d->ensureLayout();
617 return d->label->text();
618}
619
620/*!
621 \enum QInputDialog::InputDialogOption
622
623 \since 4.5
624
625 This enum specifies various options that affect the look and feel
626 of an input dialog.
627
628 \value NoButtons Don't display \uicontrol{OK} and \uicontrol{Cancel} buttons (useful for "live dialogs").
629 \value UseListViewForComboBoxItems Use a QListView rather than a non-editable QComboBox for
630 displaying the items set with setComboBoxItems().
631 \value UsePlainTextEditForTextInput Use a QPlainTextEdit for multiline text input. This value was
632 introduced in 5.2.
633
634 \sa options, setOption(), testOption()
635*/
636
637/*!
638 Sets the given \a option to be enabled if \a on is true;
639 otherwise, clears the given \a option.
640
641 \sa options, testOption()
642*/
643void QInputDialog::setOption(InputDialogOption option, bool on)
644{
645 Q_D(QInputDialog);
646 if (!(d->opts & option) != !on)
647 setOptions(d->opts ^ option);
648}
649
650/*!
651 Returns \c true if the given \a option is enabled; otherwise, returns
652 false.
653
654 \sa options, setOption()
655*/
656bool QInputDialog::testOption(InputDialogOption option) const
657{
658 Q_D(const QInputDialog);
659 return (d->opts & option) != 0;
660}
661
662/*!
663 \property QInputDialog::options
664 \brief the various options that affect the look and feel of the dialog
665 \since 4.5
666
667 By default, all options are disabled.
668
669 \sa setOption(), testOption()
670*/
671void QInputDialog::setOptions(InputDialogOptions options)
672{
673 Q_D(QInputDialog);
674
675 InputDialogOptions changed = (options ^ d->opts);
676 if (!changed)
677 return;
678
679 d->opts = options;
680 d->ensureLayout();
681
682 if (changed & NoButtons)
683 d->buttonBox->setVisible(!(options & NoButtons));
684 if ((changed & UseListViewForComboBoxItems) && inputMode() == TextInput)
685 d->chooseRightTextInputWidget();
686 if ((changed & UsePlainTextEditForTextInput) && inputMode() == TextInput)
687 d->chooseRightTextInputWidget();
688}
689
690QInputDialog::InputDialogOptions QInputDialog::options() const
691{
692 Q_D(const QInputDialog);
693 return d->opts;
694}
695
696/*!
697 \since 4.5
698
699 \property QInputDialog::textValue
700
701 \brief the text value for the input dialog
702
703 This property is only relevant when the input dialog is used in
704 TextInput mode.
705*/
706void QInputDialog::setTextValue(const QString &text)
707{
708 Q_D(QInputDialog);
709
710 setInputMode(TextInput);
711 if (d->inputWidget == d->lineEdit) {
712 d->lineEdit->setText(text);
713 } else if (d->inputWidget == d->plainTextEdit) {
714 d->plainTextEdit->setPlainText(text);
715 } else if (d->inputWidget == d->comboBox) {
716 d->setComboBoxText(text);
717 } else {
718 d->setListViewText(text);
719 }
720}
721
722QString QInputDialog::textValue() const
723{
724 Q_D(const QInputDialog);
725 return d->textValue;
726}
727
728/*!
729 \since 4.5
730
731 \property QInputDialog::textEchoMode
732
733 \brief the echo mode for the text value
734
735 This property is only relevant when the input dialog is used in
736 TextInput mode.
737*/
738void QInputDialog::setTextEchoMode(QLineEdit::EchoMode mode)
739{
740 Q_D(QInputDialog);
741 d->ensureLineEdit();
742 d->lineEdit->setEchoMode(mode);
743}
744
745QLineEdit::EchoMode QInputDialog::textEchoMode() const
746{
747 Q_D(const QInputDialog);
748 if (d->lineEdit) {
749 return d->lineEdit->echoMode();
750 } else {
751 return QLineEdit::Normal;
752 }
753}
754
755/*!
756 \since 4.5
757
758 \property QInputDialog::comboBoxEditable
759
760 \brief whether or not the combo box used in the input dialog is editable
761*/
762void QInputDialog::setComboBoxEditable(bool editable)
763{
764 Q_D(QInputDialog);
765 d->ensureComboBox();
766 d->comboBox->setEditable(editable);
767 if (inputMode() == TextInput)
768 d->chooseRightTextInputWidget();
769}
770
771bool QInputDialog::isComboBoxEditable() const
772{
773 Q_D(const QInputDialog);
774 if (d->comboBox) {
775 return d->comboBox->isEditable();
776 } else {
777 return false;
778 }
779}
780
781/*!
782 \since 4.5
783
784 \property QInputDialog::comboBoxItems
785
786 \brief the items used in the combo box for the input dialog
787*/
788void QInputDialog::setComboBoxItems(const QStringList &items)
789{
790 Q_D(QInputDialog);
791
792 d->ensureComboBox();
793 {
794 const QSignalBlocker blocker(d->comboBox);
795 d->comboBox->clear();
796 d->comboBox->addItems(items);
797 }
798
799 if (inputMode() == TextInput)
800 d->chooseRightTextInputWidget();
801}
802
803QStringList QInputDialog::comboBoxItems() const
804{
805 Q_D(const QInputDialog);
806 QStringList result;
807 if (d->comboBox) {
808 const int count = d->comboBox->count();
809 result.reserve(count);
810 for (int i = 0; i < count; ++i)
811 result.append(d->comboBox->itemText(i));
812 }
813 return result;
814}
815
816/*!
817 \property QInputDialog::intValue
818 \since 4.5
819 \brief the current integer value accepted as input
820
821 This property is only relevant when the input dialog is used in
822 IntInput mode.
823*/
824void QInputDialog::setIntValue(int value)
825{
826 Q_D(QInputDialog);
827 setInputMode(IntInput);
828 d->intSpinBox->setValue(value);
829}
830
831int QInputDialog::intValue() const
832{
833 Q_D(const QInputDialog);
834 if (d->intSpinBox) {
835 return d->intSpinBox->value();
836 } else {
837 return 0;
838 }
839}
840
841/*!
842 \property QInputDialog::intMinimum
843 \since 4.5
844 \brief the minimum integer value accepted as input
845
846 This property is only relevant when the input dialog is used in
847 IntInput mode.
848*/
849void QInputDialog::setIntMinimum(int min)
850{
851 Q_D(QInputDialog);
852 d->ensureIntSpinBox();
853 d->intSpinBox->setMinimum(min);
854}
855
856int QInputDialog::intMinimum() const
857{
858 Q_D(const QInputDialog);
859 if (d->intSpinBox) {
860 return d->intSpinBox->minimum();
861 } else {
862 return 0;
863 }
864}
865
866/*!
867 \property QInputDialog::intMaximum
868 \since 4.5
869 \brief the maximum integer value accepted as input
870
871 This property is only relevant when the input dialog is used in
872 IntInput mode.
873*/
874void QInputDialog::setIntMaximum(int max)
875{
876 Q_D(QInputDialog);
877 d->ensureIntSpinBox();
878 d->intSpinBox->setMaximum(max);
879}
880
881int QInputDialog::intMaximum() const
882{
883 Q_D(const QInputDialog);
884 if (d->intSpinBox) {
885 return d->intSpinBox->maximum();
886 } else {
887 return 99;
888 }
889}
890
891/*!
892 Sets the range of integer values accepted by the dialog when used in
893 IntInput mode, with minimum and maximum values specified by \a min and
894 \a max respectively.
895*/
896void QInputDialog::setIntRange(int min, int max)
897{
898 Q_D(QInputDialog);
899 d->ensureIntSpinBox();
900 d->intSpinBox->setRange(min, max);
901}
902
903/*!
904 \property QInputDialog::intStep
905 \since 4.5
906 \brief the step by which the integer value is increased and decreased
907
908 This property is only relevant when the input dialog is used in
909 IntInput mode.
910*/
911void QInputDialog::setIntStep(int step)
912{
913 Q_D(QInputDialog);
914 d->ensureIntSpinBox();
915 d->intSpinBox->setSingleStep(step);
916}
917
918int QInputDialog::intStep() const
919{
920 Q_D(const QInputDialog);
921 if (d->intSpinBox) {
922 return d->intSpinBox->singleStep();
923 } else {
924 return 1;
925 }
926}
927
928/*!
929 \property QInputDialog::doubleValue
930 \since 4.5
931 \brief the current double precision floating point value accepted as input
932
933 This property is only relevant when the input dialog is used in
934 DoubleInput mode.
935*/
936void QInputDialog::setDoubleValue(double value)
937{
938 Q_D(QInputDialog);
939 setInputMode(DoubleInput);
940 d->doubleSpinBox->setValue(value);
941}
942
943double QInputDialog::doubleValue() const
944{
945 Q_D(const QInputDialog);
946 if (d->doubleSpinBox) {
947 return d->doubleSpinBox->value();
948 } else {
949 return 0.0;
950 }
951}
952
953/*!
954 \property QInputDialog::doubleMinimum
955 \since 4.5
956 \brief the minimum double precision floating point value accepted as input
957
958 This property is only relevant when the input dialog is used in
959 DoubleInput mode.
960*/
961void QInputDialog::setDoubleMinimum(double min)
962{
963 Q_D(QInputDialog);
964 d->ensureDoubleSpinBox();
965 d->doubleSpinBox->setMinimum(min);
966}
967
968double QInputDialog::doubleMinimum() const
969{
970 Q_D(const QInputDialog);
971 if (d->doubleSpinBox) {
972 return d->doubleSpinBox->minimum();
973 } else {
974 return 0.0;
975 }
976}
977
978/*!
979 \property QInputDialog::doubleMaximum
980 \since 4.5
981 \brief the maximum double precision floating point value accepted as input
982
983 This property is only relevant when the input dialog is used in
984 DoubleInput mode.
985*/
986void QInputDialog::setDoubleMaximum(double max)
987{
988 Q_D(QInputDialog);
989 d->ensureDoubleSpinBox();
990 d->doubleSpinBox->setMaximum(max);
991}
992
993double QInputDialog::doubleMaximum() const
994{
995 Q_D(const QInputDialog);
996 if (d->doubleSpinBox) {
997 return d->doubleSpinBox->maximum();
998 } else {
999 return 99.99;
1000 }
1001}
1002
1003/*!
1004 Sets the range of double precision floating point values accepted by the
1005 dialog when used in DoubleInput mode, with minimum and maximum values
1006 specified by \a min and \a max respectively.
1007*/
1008void QInputDialog::setDoubleRange(double min, double max)
1009{
1010 Q_D(QInputDialog);
1011 d->ensureDoubleSpinBox();
1012 d->doubleSpinBox->setRange(min, max);
1013}
1014
1015/*!
1016 \since 4.5
1017
1018 \property QInputDialog::doubleDecimals
1019
1020 \brief sets the precision of the double spinbox in decimals
1021
1022 \sa QDoubleSpinBox::setDecimals()
1023*/
1024void QInputDialog::setDoubleDecimals(int decimals)
1025{
1026 Q_D(QInputDialog);
1027 d->ensureDoubleSpinBox();
1028 d->doubleSpinBox->setDecimals(decimals);
1029}
1030
1031int QInputDialog::doubleDecimals() const
1032{
1033 Q_D(const QInputDialog);
1034 if (d->doubleSpinBox) {
1035 return d->doubleSpinBox->decimals();
1036 } else {
1037 return 2;
1038 }
1039}
1040
1041/*!
1042 \since 4.5
1043
1044 \property QInputDialog::okButtonText
1045
1046 \brief the text for the button used to accept the entry in the dialog
1047*/
1048void QInputDialog::setOkButtonText(const QString &text)
1049{
1050 Q_D(const QInputDialog);
1051 d->ensureLayout();
1052 d->buttonBox->button(QDialogButtonBox::Ok)->setText(text);
1053}
1054
1055QString QInputDialog::okButtonText() const
1056{
1057 Q_D(const QInputDialog);
1058 d->ensureLayout();
1059 return d->buttonBox->button(QDialogButtonBox::Ok)->text();
1060}
1061
1062/*!
1063 \since 4.5
1064
1065 \property QInputDialog::cancelButtonText
1066 \brief the text for the button used to cancel the dialog
1067*/
1068void QInputDialog::setCancelButtonText(const QString &text)
1069{
1070 Q_D(const QInputDialog);
1071 d->ensureLayout();
1072 d->buttonBox->button(QDialogButtonBox::Cancel)->setText(text);
1073}
1074
1075QString QInputDialog::cancelButtonText() const
1076{
1077 Q_D(const QInputDialog);
1078 d->ensureLayout();
1079 return d->buttonBox->button(QDialogButtonBox::Cancel)->text();
1080}
1081
1082/*!
1083 \since 4.5
1084
1085 This function connects one of its signals to the slot specified by \a receiver
1086 and \a member. The specific signal depends on the arguments that are specified
1087 in \a member. These are:
1088
1089 \list
1090 \li textValueSelected() if \a member has a QString for its first argument.
1091 \li intValueSelected() if \a member has an int for its first argument.
1092 \li doubleValueSelected() if \a member has a double for its first argument.
1093 \li accepted() if \a member has NO arguments.
1094 \endlist
1095
1096 The signal will be disconnected from the slot when the dialog is closed.
1097*/
1098void QInputDialog::open(QObject *receiver, const char *member)
1099{
1100 Q_D(QInputDialog);
1101 connect(this, signalForMember(member), receiver, member);
1102 d->receiverToDisconnectOnClose = receiver;
1103 d->memberToDisconnectOnClose = member;
1104 QDialog::open();
1105}
1106
1107/*!
1108 \reimp
1109*/
1110QSize QInputDialog::minimumSizeHint() const
1111{
1112 Q_D(const QInputDialog);
1113 d->ensureLayout();
1114 return QDialog::minimumSizeHint();
1115}
1116
1117/*!
1118 \reimp
1119*/
1120QSize QInputDialog::sizeHint() const
1121{
1122 Q_D(const QInputDialog);
1123 d->ensureLayout();
1124 return QDialog::sizeHint();
1125}
1126
1127/*!
1128 \reimp
1129*/
1130void QInputDialog::setVisible(bool visible)
1131{
1132 Q_D(const QInputDialog);
1133 if (visible) {
1134 d->ensureLayout();
1135 d->inputWidget->setFocus();
1136 if (d->inputWidget == d->lineEdit) {
1137 d->lineEdit->selectAll();
1138 } else if (d->inputWidget == d->plainTextEdit) {
1139 d->plainTextEdit->selectAll();
1140 } else if (d->inputWidget == d->intSpinBox) {
1141 d->intSpinBox->selectAll();
1142 } else if (d->inputWidget == d->doubleSpinBox) {
1143 d->doubleSpinBox->selectAll();
1144 }
1145 }
1146 QDialog::setVisible(visible);
1147}
1148
1149/*!
1150 Closes the dialog and sets its result code to \a result. If this dialog
1151 is shown with exec(), done() causes the local event loop to finish,
1152 and exec() to return \a result.
1153
1154 \sa QDialog::done()
1155*/
1156void QInputDialog::done(int result)
1157{
1158 Q_D(QInputDialog);
1159 QDialog::done(result);
1160 if (result) {
1161 InputMode mode = inputMode();
1162 switch (mode) {
1163 case DoubleInput:
1164 emit doubleValueSelected(doubleValue());
1165 break;
1166 case IntInput:
1167 emit intValueSelected(intValue());
1168 break;
1169 default:
1170 Q_ASSERT(mode == TextInput);
1171 emit textValueSelected(textValue());
1172 }
1173 }
1174 if (d->receiverToDisconnectOnClose) {
1175 disconnect(this, signalForMember(d->memberToDisconnectOnClose),
1176 d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
1177 d->receiverToDisconnectOnClose = nullptr;
1178 }
1179 d->memberToDisconnectOnClose.clear();
1180}
1181
1182/*!
1183 Static convenience function to get a string from the user.
1184
1185 \a title is the text which is displayed in the title bar of the dialog.
1186 \a label is the text which is shown to the user (it should say what should
1187 be entered).
1188 \a text is the default text which is placed in the line edit.
1189 \a mode is the echo mode the line edit will use.
1190 \a inputMethodHints is the input method hints that will be used in the
1191 edit widget if an input method is active.
1192
1193 If \a ok is nonnull \e {*ok} will be set to true if the user pressed
1194 \uicontrol OK and to false if the user pressed \uicontrol Cancel. The dialog's parent
1195 is \a parent. The dialog will be modal and uses the specified widget
1196 \a flags.
1197
1198 If the dialog is accepted, this function returns the text in the dialog's
1199 line edit. If the dialog is rejected, a null QString is returned.
1200
1201 Use this static function like this:
1202
1203 \snippet dialogs/standarddialogs/dialog.cpp 3
1204
1205 \sa getInt(), getDouble(), getItem(), getMultiLineText()
1206*/
1207
1208QString QInputDialog::getText(QWidget *parent, const QString &title, const QString &label,
1209 QLineEdit::EchoMode mode, const QString &text, bool *ok,
1210 Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints)
1211{
1212 QAutoPointer<QInputDialog> dialog(new QInputDialog(parent, flags));
1213 dialog->setWindowTitle(title);
1214 dialog->setLabelText(label);
1215 dialog->setTextValue(text);
1216 dialog->setTextEchoMode(mode);
1217 dialog->setInputMethodHints(inputMethodHints);
1218
1219 const int ret = dialog->exec();
1220 if (ok)
1221 *ok = !!ret;
1222 if (ret) {
1223 return dialog->textValue();
1224 } else {
1225 return QString();
1226 }
1227}
1228
1229/*!
1230 \since 5.2
1231
1232 Static convenience function to get a multiline string from the user.
1233
1234 \a title is the text which is displayed in the title bar of the dialog.
1235 \a label is the text which is shown to the user (it should say what should
1236 be entered).
1237 \a text is the default text which is placed in the plain text edit.
1238 \a inputMethodHints is the input method hints that will be used in the
1239 edit widget if an input method is active.
1240
1241 If \a ok is nonnull \e {*ok} will be set to true if the user pressed
1242 \uicontrol OK and to false if the user pressed \uicontrol Cancel. The dialog's parent
1243 is \a parent. The dialog will be modal and uses the specified widget
1244 \a flags.
1245
1246 If the dialog is accepted, this function returns the text in the dialog's
1247 plain text edit. If the dialog is rejected, a null QString is returned.
1248
1249 Use this static function like this:
1250
1251 \snippet dialogs/standarddialogs/dialog.cpp 4
1252
1253 \sa getInt(), getDouble(), getItem(), getText()
1254*/
1255
1256QString QInputDialog::getMultiLineText(QWidget *parent, const QString &title, const QString &label,
1257 const QString &text, bool *ok, Qt::WindowFlags flags,
1258 Qt::InputMethodHints inputMethodHints)
1259{
1260 QAutoPointer<QInputDialog> dialog(new QInputDialog(parent, flags));
1261 dialog->setOptions(QInputDialog::UsePlainTextEditForTextInput);
1262 dialog->setWindowTitle(title);
1263 dialog->setLabelText(label);
1264 dialog->setTextValue(text);
1265 dialog->setInputMethodHints(inputMethodHints);
1266
1267 const int ret = dialog->exec();
1268 if (ok)
1269 *ok = !!ret;
1270 if (ret) {
1271 return dialog->textValue();
1272 } else {
1273 return QString();
1274 }
1275}
1276
1277/*!
1278 \since 4.5
1279
1280 Static convenience function to get an integer input from the user.
1281
1282 \a title is the text which is displayed in the title bar of the dialog.
1283 \a label is the text which is shown to the user (it should say what should
1284 be entered).
1285 \a value is the default integer which the spinbox will be set to.
1286 \a min and \a max are the minimum and maximum values the user may choose.
1287 \a step is the amount by which the values change as the user presses the
1288 arrow buttons to increment or decrement the value.
1289
1290 If \a ok is nonnull *\a ok will be set to true if the user pressed \uicontrol OK
1291 and to false if the user pressed \uicontrol Cancel. The dialog's parent is
1292 \a parent. The dialog will be modal and uses the widget \a flags.
1293
1294 On success, this function returns the integer which has been entered by the
1295 user; on failure, it returns the initial \a value.
1296
1297 Use this static function like this:
1298
1299 \snippet dialogs/standarddialogs/dialog.cpp 0
1300
1301 \sa getText(), getDouble(), getItem(), getMultiLineText()
1302*/
1303
1304int QInputDialog::getInt(QWidget *parent, const QString &title, const QString &label, int value,
1305 int min, int max, int step, bool *ok, Qt::WindowFlags flags)
1306{
1307 QAutoPointer<QInputDialog> dialog(new QInputDialog(parent, flags));
1308 dialog->setWindowTitle(title);
1309 dialog->setLabelText(label);
1310 dialog->setIntRange(min, max);
1311 dialog->setIntValue(value);
1312 dialog->setIntStep(step);
1313
1314 const int ret = dialog->exec();
1315 if (ok)
1316 *ok = !!ret;
1317 if (ret) {
1318 return dialog->intValue();
1319 } else {
1320 return value;
1321 }
1322}
1323
1324/*!
1325 Static convenience function to get a floating point number from the user.
1326
1327 \a title is the text which is displayed in the title bar of the dialog.
1328 \a label is the text which is shown to the user (it should say what should
1329 be entered).
1330 \a value is the default floating point number that the line edit will be
1331 set to.
1332 \a min and \a max are the minimum and maximum values the user may choose.
1333 \a decimals is the maximum number of decimal places the number may have.
1334 \a step is the amount by which the values change as the user presses the
1335 arrow buttons to increment or decrement the value.
1336
1337 If \a ok is nonnull, *\a ok will be set to true if the user pressed \uicontrol OK
1338 and to false if the user pressed \uicontrol Cancel. The dialog's parent is
1339 \a parent. The dialog will be modal and uses the widget \a flags.
1340
1341 This function returns the floating point number which has been entered by
1342 the user.
1343
1344 Use this static function like this:
1345
1346 \snippet dialogs/standarddialogs/dialog.cpp 1
1347
1348 \sa getText(), getInt(), getItem(), getMultiLineText()
1349*/
1350
1351double QInputDialog::getDouble(QWidget *parent, const QString &title, const QString &label,
1352 double value, double min, double max, int decimals, bool *ok,
1353 Qt::WindowFlags flags, double step)
1354{
1355 QAutoPointer<QInputDialog> dialog(new QInputDialog(parent, flags));
1356 dialog->setWindowTitle(title);
1357 dialog->setLabelText(label);
1358 dialog->setDoubleDecimals(decimals);
1359 dialog->setDoubleRange(min, max);
1360 dialog->setDoubleValue(value);
1361 dialog->setDoubleStep(step);
1362
1363 const int ret = dialog->exec();
1364 if (ok)
1365 *ok = !!ret;
1366 if (ret) {
1367 return dialog->doubleValue();
1368 } else {
1369 return value;
1370 }
1371}
1372
1373/*!
1374 Static convenience function to let the user select an item from a string
1375 list.
1376
1377 \a title is the text which is displayed in the title bar of the dialog.
1378 \a label is the text which is shown to the user (it should say what should
1379 be entered).
1380 \a items is the string list which is inserted into the combo box.
1381 \a current is the number of the item which should be the current item.
1382 \a inputMethodHints is the input method hints that will be used if the
1383 combo box is editable and an input method is active.
1384
1385 If \a editable is true the user can enter their own text; otherwise, the
1386 user may only select one of the existing items.
1387
1388 If \a ok is nonnull \e {*ok} will be set to true if the user pressed
1389 \uicontrol OK and to false if the user pressed \uicontrol Cancel. The dialog's parent
1390 is \a parent. The dialog will be modal and uses the widget \a flags.
1391
1392 This function returns the text of the current item, or if \a editable is
1393 true, the current text of the combo box.
1394
1395 Use this static function like this:
1396
1397 \snippet dialogs/standarddialogs/dialog.cpp 2
1398
1399 \sa getText(), getInt(), getDouble(), getMultiLineText()
1400*/
1401
1402QString QInputDialog::getItem(QWidget *parent, const QString &title, const QString &label,
1403 const QStringList &items, int current, bool editable, bool *ok,
1404 Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints)
1405{
1406 QString text(items.value(current));
1407
1408 QAutoPointer<QInputDialog> dialog(new QInputDialog(parent, flags));
1409 dialog->setWindowTitle(title);
1410 dialog->setLabelText(label);
1411 dialog->setComboBoxItems(items);
1412 dialog->setTextValue(text);
1413 dialog->setComboBoxEditable(editable);
1414 dialog->setInputMethodHints(inputMethodHints);
1415
1416 const int ret = dialog->exec();
1417 if (ok)
1418 *ok = !!ret;
1419 if (ret) {
1420 return dialog->textValue();
1421 } else {
1422 return text;
1423 }
1424}
1425
1426/*!
1427 \property QInputDialog::doubleStep
1428 \since 5.10
1429 \brief the step by which the double value is increased and decreased
1430
1431 This property is only relevant when the input dialog is used in
1432 DoubleInput mode.
1433*/
1434
1435void QInputDialog::setDoubleStep(double step)
1436{
1437 Q_D(QInputDialog);
1438 d->ensureDoubleSpinBox();
1439 d->doubleSpinBox->setSingleStep(step);
1440}
1441
1442double QInputDialog::doubleStep() const
1443{
1444 Q_D(const QInputDialog);
1445 if (d->doubleSpinBox)
1446 return d->doubleSpinBox->singleStep();
1447 else
1448 return 1.0;
1449}
1450
1451/*!
1452 \fn void QInputDialog::doubleValueChanged(double value)
1453
1454 This signal is emitted whenever the double value changes in the dialog.
1455 The current value is specified by \a value.
1456
1457 This signal is only relevant when the input dialog is used in
1458 DoubleInput mode.
1459*/
1460
1461/*!
1462 \fn void QInputDialog::doubleValueSelected(double value)
1463
1464 This signal is emitted whenever the user selects a double value by
1465 accepting the dialog; for example, by clicking the \uicontrol{OK} button.
1466 The selected value is specified by \a value.
1467
1468 This signal is only relevant when the input dialog is used in
1469 DoubleInput mode.
1470*/
1471
1472/*!
1473 \fn void QInputDialog::intValueChanged(int value)
1474
1475 This signal is emitted whenever the integer value changes in the dialog.
1476 The current value is specified by \a value.
1477
1478 This signal is only relevant when the input dialog is used in
1479 IntInput mode.
1480*/
1481
1482/*!
1483 \fn void QInputDialog::intValueSelected(int value)
1484
1485 This signal is emitted whenever the user selects a integer value by
1486 accepting the dialog; for example, by clicking the \uicontrol{OK} button.
1487 The selected value is specified by \a value.
1488
1489 This signal is only relevant when the input dialog is used in
1490 IntInput mode.
1491*/
1492
1493/*!
1494 \fn void QInputDialog::textValueChanged(const QString &text)
1495
1496 This signal is emitted whenever the text string changes in the dialog.
1497 The current string is specified by \a text.
1498
1499 This signal is only relevant when the input dialog is used in
1500 TextInput mode.
1501*/
1502
1503/*!
1504 \fn void QInputDialog::textValueSelected(const QString &text)
1505
1506 This signal is emitted whenever the user selects a text string by
1507 accepting the dialog; for example, by clicking the \uicontrol{OK} button.
1508 The selected string is specified by \a text.
1509
1510 This signal is only relevant when the input dialog is used in
1511 TextInput mode.
1512*/
1513
1514QT_END_NAMESPACE
1515
1516#include "qinputdialog.moc"
1517#include "moc_qinputdialog.cpp"
1518