File indexing completed on 2024-04-14 14:20:21

0001 /*
0002   Copyright (C) 2003 Nadeem Hasan <nhasan@kde.org>
0003 
0004   This library is free software; you can redistribute it and/or
0005   modify it under the terms of the GNU Library General Public
0006   License as published by the Free Software Foundation; either
0007   version 2 of the License, or (at your option) any later version.
0008 
0009   This library is distributed in the hope that it will be useful,
0010   but WITHOUT ANY WARRANTY; without even the implied warranty of
0011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012   Library General Public License for more details.
0013 
0014   You should have received a copy of the GNU Library General Public License
0015   along with this library; see the file COPYING.LIB.  If not, write to
0016   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017   Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #include "kinputdialog.h"
0021 #include "kinputdialog_p.h"
0022 
0023 #include <QDialogButtonBox>
0024 #include <QDoubleValidator>
0025 #include <QLabel>
0026 #include <QLayout>
0027 #include <QPushButton>
0028 #include <QListWidget>
0029 #include <QSpinBox>
0030 
0031 #include <kcombobox.h>
0032 #include <kcompletion.h>
0033 #include <kguiitem.h>
0034 #include <klineedit.h>
0035 #include <kstandardguiitem.h>
0036 #include <ktextedit.h>
0037 
0038 KInputDialogHelper::KInputDialogHelper(const QString &caption, const QString &label,
0039                                        const QString &value, QWidget *parent,
0040                                        QValidator *validator, const QString &mask)
0041     : QDialog(parent),
0042       m_label(nullptr), m_lineEdit(nullptr), m_intSpinBox(nullptr),
0043       m_doubleSpinBox(nullptr), m_comboBox(nullptr), m_listBox(nullptr), m_buttonBox(nullptr)
0044 {
0045     setWindowTitle(caption);
0046     setModal(true);
0047 
0048     QVBoxLayout *layout = new QVBoxLayout;
0049     setLayout(layout);
0050 
0051     m_label = new QLabel(label, this);
0052     m_label->setWordWrap(true);
0053     layout->addWidget(m_label);
0054 
0055     m_lineEdit = new KLineEdit(value, this);
0056     m_lineEdit->setClearButtonShown(true);
0057     layout->addWidget(m_lineEdit);
0058 
0059     m_lineEdit->setFocus();
0060     m_label->setBuddy(m_lineEdit);
0061 
0062     layout->addStretch();
0063 
0064     m_buttonBox = new QDialogButtonBox(this);
0065     m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0066     connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
0067     connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
0068     layout->addWidget(m_buttonBox);
0069 
0070     if (validator) {
0071         m_lineEdit->setValidator(validator);
0072     }
0073 
0074     if (!mask.isEmpty()) {
0075         m_lineEdit->setInputMask(mask);
0076     }
0077 
0078     connect(m_lineEdit, SIGNAL(textChanged(QString)),
0079             SLOT(slotEditTextChanged(QString)));
0080 
0081     slotEditTextChanged(value);
0082     setMinimumWidth(350);
0083 }
0084 
0085 KInputDialogHelper::KInputDialogHelper(const QString &caption, const QString &label,
0086                                        const QString &value, QWidget *parent)
0087     : QDialog(parent),
0088       m_label(nullptr), m_lineEdit(nullptr), m_intSpinBox(nullptr),
0089       m_doubleSpinBox(nullptr), m_comboBox(nullptr), m_buttonBox(nullptr)
0090 {
0091     setWindowTitle(caption);
0092     setModal(true);
0093     QVBoxLayout *layout = new QVBoxLayout;
0094     setLayout(layout);
0095 
0096     m_label = new QLabel(label, this);
0097     m_label->setWordWrap(true);
0098     layout->addWidget(m_label);
0099 
0100     m_textEdit = new KTextEdit(this);
0101     m_textEdit->insertPlainText(value);
0102     layout->addWidget(m_textEdit, 10);
0103 
0104     m_textEdit->setFocus();
0105     m_label->setBuddy(m_textEdit);
0106 
0107     m_buttonBox = new QDialogButtonBox(this);
0108     QPushButton *clearButton = new QPushButton(m_buttonBox);
0109     KGuiItem::assign(clearButton, KStandardGuiItem::clear());
0110     m_buttonBox->addButton(clearButton, QDialogButtonBox::ActionRole);
0111     m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0112     connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
0113     connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
0114     layout->addWidget(m_buttonBox);
0115 
0116     connect(clearButton, SIGNAL(clicked()), m_textEdit, SLOT(clear()));
0117     connect(clearButton, SIGNAL(clicked()), m_textEdit, SLOT(setFocus()));
0118     setMinimumWidth(400);
0119 }
0120 
0121 KInputDialogHelper::KInputDialogHelper(const QString &caption, const QString &label,
0122                                        int value, int minValue, int maxValue, int step, int base,
0123                                        QWidget *parent)
0124     : QDialog(parent),
0125       m_label(nullptr), m_lineEdit(nullptr), m_intSpinBox(nullptr),
0126       m_doubleSpinBox(nullptr), m_comboBox(nullptr), m_listBox(nullptr), m_buttonBox(nullptr)
0127 {
0128     setWindowTitle(caption);
0129     setModal(true);
0130 
0131     QVBoxLayout *layout = new QVBoxLayout;
0132     setLayout(layout);
0133 
0134     m_label = new QLabel(label, this);
0135     m_label->setWordWrap(true);
0136     layout->addWidget(m_label);
0137 
0138     m_intSpinBox = new QSpinBox(this);
0139     m_intSpinBox->setMinimum(minValue);
0140     m_intSpinBox->setMaximum(maxValue);
0141     m_intSpinBox->setSingleStep(step);
0142     m_intSpinBox->setValue(value);
0143     m_intSpinBox->setDisplayIntegerBase(base);
0144 
0145     layout->addWidget(m_intSpinBox);
0146 
0147     layout->addStretch();
0148 
0149     m_buttonBox = new QDialogButtonBox(this);
0150     m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0151     connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
0152     connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
0153     layout->addWidget(m_buttonBox);
0154 
0155     m_intSpinBox->setFocus();
0156     setMinimumWidth(300);
0157 }
0158 
0159 KInputDialogHelper::KInputDialogHelper(const QString &caption, const QString &label,
0160                                        double value, double minValue, double maxValue, double step, int decimals,
0161                                        QWidget *parent)
0162     : QDialog(parent),
0163       m_label(nullptr), m_lineEdit(nullptr), m_intSpinBox(nullptr),
0164       m_doubleSpinBox(nullptr), m_comboBox(nullptr), m_listBox(nullptr), m_buttonBox(nullptr)
0165 {
0166     setWindowTitle(caption);
0167     setModal(true);
0168 
0169     QVBoxLayout *layout = new QVBoxLayout;
0170     setLayout(layout);
0171 
0172     m_label = new QLabel(label, this);
0173     m_label->setWordWrap(true);
0174     layout->addWidget(m_label);
0175 
0176     m_doubleSpinBox = new QDoubleSpinBox(this);
0177     m_doubleSpinBox->setRange(minValue, maxValue);
0178     m_doubleSpinBox->setSingleStep(step);
0179     m_doubleSpinBox->setValue(value);
0180     m_doubleSpinBox->setDecimals(decimals);
0181 
0182     layout->addWidget(m_doubleSpinBox);
0183 
0184     layout->addStretch();
0185 
0186     m_buttonBox = new QDialogButtonBox(this);
0187     m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0188     connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
0189     connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
0190     layout->addWidget(m_buttonBox);
0191 
0192     m_doubleSpinBox->setFocus();
0193     setMinimumWidth(300);
0194 }
0195 
0196 KInputDialogHelper::KInputDialogHelper(const QString &caption, const QString &label,
0197                                        const QStringList &list, int current, bool editable, QWidget *parent)
0198     : QDialog(parent),
0199       m_label(nullptr), m_lineEdit(nullptr), m_intSpinBox(nullptr),
0200       m_doubleSpinBox(nullptr), m_comboBox(nullptr), m_listBox(nullptr), m_buttonBox(nullptr)
0201 {
0202     setWindowTitle(caption);
0203     setModal(true);
0204 
0205     QVBoxLayout *layout = new QVBoxLayout;
0206     setLayout(layout);
0207 
0208     m_label = new QLabel(label, this);
0209     m_label->setWordWrap(true);
0210     layout->addWidget(m_label);
0211 
0212     if (editable) {
0213         m_comboBox = new KComboBox(editable, this);
0214         m_lineEdit = new KLineEdit(this);
0215         m_lineEdit->setClearButtonShown(true);
0216         m_comboBox->setLineEdit(m_lineEdit);
0217         m_comboBox->insertItems(0, list);
0218         m_comboBox->setCurrentIndex(current);
0219         layout->addWidget(m_comboBox);
0220 
0221         connect(m_comboBox, SIGNAL(editTextChanged(QString)),
0222                 SLOT(slotUpdateButtons(QString)));
0223         m_comboBox->setFocus();
0224     } else {
0225         m_listBox = new QListWidget(this);
0226         m_listBox->addItems(list);
0227         m_listBox->setCurrentRow(current);
0228         layout->addWidget(m_listBox, 10);
0229         connect(m_listBox, SIGNAL(itemActivated(QListWidgetItem*)),
0230                 SLOT(accept()));
0231         m_listBox->setFocus();
0232     }
0233 
0234     layout->addStretch();
0235 
0236     m_buttonBox = new QDialogButtonBox(this);
0237     m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0238     connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
0239     connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
0240     layout->addWidget(m_buttonBox);
0241 
0242     if (editable) {
0243         slotUpdateButtons(m_comboBox->currentText());
0244     }
0245     setMinimumWidth(320);
0246 }
0247 
0248 KInputDialogHelper::KInputDialogHelper(const QString &caption, const QString &label,
0249                                        const QStringList &list, const QStringList &select, bool multiple,
0250                                        QWidget *parent)
0251     : QDialog(parent),
0252       m_label(nullptr), m_lineEdit(nullptr), m_intSpinBox(nullptr),
0253       m_doubleSpinBox(nullptr), m_comboBox(nullptr), m_listBox(nullptr), m_buttonBox(nullptr)
0254 {
0255     setWindowTitle(caption);
0256     setModal(true);
0257 
0258     QVBoxLayout *layout = new QVBoxLayout;
0259     setLayout(layout);
0260 
0261     m_label = new QLabel(label, this);
0262     m_label->setWordWrap(true);
0263     layout->addWidget(m_label);
0264 
0265     m_listBox = new QListWidget(this);
0266     m_listBox->addItems(list);
0267     layout->addWidget(m_listBox);
0268 
0269     if (multiple) {
0270         m_listBox->setSelectionMode(QAbstractItemView::ExtendedSelection);
0271 
0272         for (QStringList::ConstIterator it = select.begin(); it != select.end(); ++it) {
0273             const QList<QListWidgetItem *> matches = m_listBox->findItems(*it, Qt::MatchCaseSensitive | Qt::MatchExactly);
0274             if (!matches.isEmpty()) {
0275                 m_listBox->setCurrentItem(matches.first());
0276             }
0277         }
0278     } else {
0279         connect(m_listBox, SIGNAL(itemActivated(QListWidgetItem*)), SLOT(accept()));
0280 
0281         if (!select.isEmpty()) {
0282             QString text = select.first();
0283 
0284             const QList<QListWidgetItem *> matches = m_listBox->findItems(text, Qt::MatchCaseSensitive | Qt::MatchExactly);
0285             if (!matches.isEmpty()) {
0286                 m_listBox->setCurrentItem(matches.first());
0287             }
0288         }
0289     }
0290 
0291     m_listBox->setFocus();
0292 
0293     layout->addStretch();
0294 
0295     m_buttonBox = new QDialogButtonBox(this);
0296     m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0297     connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
0298     connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
0299     layout->addWidget(m_buttonBox);
0300 
0301     setMinimumWidth(320);
0302 }
0303 
0304 KInputDialogHelper::~KInputDialogHelper()
0305 {
0306 }
0307 
0308 void KInputDialogHelper::slotEditTextChanged(const QString &text)
0309 {
0310     bool on;
0311 
0312     if (m_lineEdit->validator()) {
0313         QString str = m_lineEdit->text();
0314         int index = m_lineEdit->cursorPosition();
0315         on = (m_lineEdit->validator()->validate(str, index) == QValidator::Acceptable);
0316     } else {
0317         on = !text.trimmed().isEmpty();
0318     }
0319 
0320     m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(on);
0321 }
0322 
0323 void KInputDialogHelper::slotUpdateButtons(const QString &text)
0324 {
0325     m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!text.isEmpty());
0326 }
0327 
0328 KLineEdit *KInputDialogHelper::lineEdit() const
0329 {
0330     return m_lineEdit;
0331 }
0332 
0333 QSpinBox *KInputDialogHelper::intSpinBox() const
0334 {
0335     return m_intSpinBox;
0336 }
0337 
0338 QDoubleSpinBox *KInputDialogHelper::doubleSpinBox() const
0339 {
0340     return m_doubleSpinBox;
0341 }
0342 
0343 KComboBox *KInputDialogHelper::comboBox() const
0344 {
0345     return m_comboBox;
0346 }
0347 
0348 QListWidget *KInputDialogHelper::listBox() const
0349 {
0350     return m_listBox;
0351 }
0352 
0353 KTextEdit *KInputDialogHelper::textEdit() const
0354 {
0355     return m_textEdit;
0356 }
0357 
0358 // KInputDialog namespace
0359 
0360 namespace KInputDialog
0361 {
0362 
0363 QString getText(const QString &caption,
0364                 const QString &label, const QString &value, bool *ok, QWidget *parent,
0365                 QValidator *validator, const QString &mask,
0366                 const QString &whatsThis, const QStringList &completionList)
0367 {
0368     KInputDialogHelper dlg(caption, label, value, parent, validator, mask);
0369 
0370     if (!whatsThis.isEmpty()) {
0371         dlg.lineEdit()->setWhatsThis(whatsThis);
0372     }
0373 
0374     if (!completionList.isEmpty()) {
0375         KCompletion *comp = dlg.lineEdit()->completionObject();
0376         for (QStringList::const_iterator it = completionList.constBegin(); it != completionList.constEnd(); ++it) {
0377             comp->addItem(*it);
0378         }
0379     }
0380 
0381     bool _ok = (dlg.exec() == QDialog::Accepted);
0382 
0383     if (ok) {
0384         *ok = _ok;
0385     }
0386 
0387     QString result;
0388     if (_ok) {
0389         result = dlg.lineEdit()->text();
0390     }
0391 
0392     // A validator may explicitly allow leading and trailing whitespace
0393     if (!validator) {
0394         result = result.trimmed();
0395     }
0396 
0397     return result;
0398 }
0399 
0400 QString getMultiLineText(const QString &caption,
0401                          const QString &label, const QString &value, bool *ok,
0402                          QWidget *parent)
0403 {
0404     KInputDialogHelper dlg(caption, label, value, parent);
0405     dlg.textEdit()->setAcceptRichText(false);
0406     bool _ok = (dlg.exec() == QDialog::Accepted);
0407 
0408     if (ok) {
0409         *ok = _ok;
0410     }
0411 
0412     QString result;
0413     if (_ok) {
0414         result = dlg.textEdit()->toPlainText();
0415     }
0416 
0417     return result;
0418 }
0419 
0420 int getInteger(const QString &caption, const QString &label,
0421                int value, int minValue, int maxValue, int step, int base, bool *ok,
0422                QWidget *parent)
0423 {
0424     KInputDialogHelper dlg(caption, label, value, minValue, maxValue, step, base, parent);
0425 
0426     bool _ok = (dlg.exec() == QDialog::Accepted);
0427 
0428     if (ok) {
0429         *ok = _ok;
0430     }
0431 
0432     int result = 0;
0433     if (_ok) {
0434         result = dlg.intSpinBox()->value();
0435     }
0436 
0437     return result;
0438 }
0439 
0440 int getInteger(const QString &caption, const QString &label,
0441                int value, int minValue, int maxValue, int step, bool *ok,
0442                QWidget *parent)
0443 {
0444     return getInteger(caption, label, value, minValue, maxValue, step, 10, ok, parent);
0445 }
0446 
0447 double getDouble(const QString &caption, const QString &label,
0448                  double value, double minValue, double maxValue, double step, int decimals,
0449                  bool *ok, QWidget *parent)
0450 {
0451     KInputDialogHelper dlg(caption, label, value, minValue, maxValue, step, decimals, parent);
0452 
0453     bool _ok = (dlg.exec() == QDialog::Accepted);
0454 
0455     if (ok) {
0456         *ok = _ok;
0457     }
0458 
0459     double result = 0;
0460     if (_ok) {
0461         result = dlg.doubleSpinBox()->value();
0462     }
0463 
0464     return result;
0465 }
0466 
0467 double getDouble(const QString &caption, const QString &label,
0468                  double value, double minValue, double maxValue, int decimals,
0469                  bool *ok, QWidget *parent)
0470 {
0471     return getDouble(caption, label, value, minValue, maxValue, 0.1, decimals, ok, parent);
0472 }
0473 
0474 QString getItem(const QString &caption, const QString &label,
0475                 const QStringList &list, int current, bool editable, bool *ok,
0476                 QWidget *parent)
0477 {
0478     KInputDialogHelper dlg(caption, label, list, current, editable, parent);
0479 
0480     if (!editable) {
0481         dlg.connect(dlg.listBox(), SIGNAL(itemActivated(QListWidgetItem*)), &dlg, SLOT(accept()));
0482     }
0483 
0484     bool _ok = (dlg.exec() == QDialog::Accepted);
0485 
0486     if (ok) {
0487         *ok = _ok;
0488     }
0489 
0490     QString result;
0491     if (_ok) {
0492         if (editable) {
0493             result = dlg.comboBox()->currentText();
0494         } else if (dlg.listBox()->currentItem()) {
0495             result = dlg.listBox()->currentItem()->text();
0496         }
0497     }
0498 
0499     return result;
0500 }
0501 
0502 QStringList getItemList(const QString &caption,
0503                         const QString &label, const QStringList &list, const QStringList &select,
0504                         bool multiple, bool *ok, QWidget *parent)
0505 {
0506     KInputDialogHelper dlg(caption, label, list, select, multiple, parent);
0507 
0508     bool _ok = (dlg.exec() == QDialog::Accepted);
0509 
0510     if (ok) {
0511         *ok = _ok;
0512     }
0513 
0514     QStringList result;
0515     if (_ok) {
0516         for (int i = 0; i < dlg.listBox()->count(); i++) {
0517 
0518             QListWidgetItem *item = dlg.listBox()->item(i);
0519 
0520             if (item->isSelected()) {
0521                 result.append(item->text());
0522             }
0523         }
0524     }
0525 
0526     return result;
0527 }
0528 
0529 }
0530 
0531 #include "moc_kinputdialog_p.cpp"
0532