File indexing completed on 2024-05-12 05:09:48
0001 /*************************************************************************** 0002 Copyright (C) 2005-2009 Robby Stephenson <robby@periapsis.org> 0003 ***************************************************************************/ 0004 0005 /*************************************************************************** 0006 * * 0007 * This program is free software; you can redistribute it and/or * 0008 * modify it under the terms of the GNU General Public License as * 0009 * published by the Free Software Foundation; either version 2 of * 0010 * the License or (at your option) version 3 or any later version * 0011 * accepted by the membership of KDE e.V. (or its successor approved * 0012 * by the membership of KDE e.V.), which shall act as a proxy * 0013 * defined in Section 14 of version 3 of the license. * 0014 * * 0015 * This program is distributed in the hope that it will be useful, * 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0018 * GNU General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License * 0021 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0022 * * 0023 ***************************************************************************/ 0024 0025 #include "numberfieldwidget.h" 0026 #include "spinbox.h" 0027 #include "../field.h" 0028 #include "../fieldformat.h" 0029 #include "../tellico_debug.h" 0030 0031 #include <QLineEdit> 0032 #include <QValidator> 0033 #include <QBoxLayout> 0034 0035 #include <limits> 0036 0037 using Tellico::GUI::NumberFieldWidget; 0038 0039 NumberFieldWidget::NumberFieldWidget(Tellico::Data::FieldPtr field_, QWidget* parent_) 0040 : FieldWidget(field_, parent_), m_lineEdit(nullptr), m_spinBox(nullptr) { 0041 0042 if(field_->hasFlag(Data::Field::AllowMultiple)) { 0043 initLineEdit(); 0044 } else { 0045 initSpinBox(); 0046 } 0047 0048 registerWidget(); 0049 } 0050 0051 void NumberFieldWidget::initLineEdit() { 0052 m_lineEdit = new QLineEdit(this); 0053 connect(m_lineEdit, &QLineEdit::textChanged, this, &NumberFieldWidget::checkModified); 0054 0055 // regexp is any number of digits followed optionally by any number of 0056 // groups of a semi-colon followed optionally by a space, followed by digits 0057 QRegularExpression rx(QLatin1String("-?\\d*(; ?-?\\d*)*")); 0058 m_lineEdit->setValidator(new QRegularExpressionValidator(rx, this)); 0059 } 0060 0061 void NumberFieldWidget::initSpinBox() { 0062 // intentionally allow only positive numbers. -1 means non empty 0063 m_spinBox = new GUI::SpinBox(-1, std::numeric_limits<int>::max(), this); 0064 m_spinBox->setValue(-1); 0065 #if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) 0066 void (GUI::SpinBox::* textChanged)(const QString&) = &GUI::SpinBox::valueChanged; 0067 #else 0068 void (GUI::SpinBox::* textChanged)(const QString&) = &GUI::SpinBox::textChanged; 0069 #endif 0070 connect(m_spinBox, textChanged, this, &NumberFieldWidget::checkModified); 0071 } 0072 0073 QString NumberFieldWidget::text() const { 0074 if(isSpinBox()) { 0075 return m_spinBox->cleanText(); 0076 } 0077 0078 QString text = m_lineEdit->text(); 0079 if(field()->hasFlag(Data::Field::AllowMultiple)) { 0080 text = FieldFormat::fixupValue(text); 0081 } 0082 return text.simplified(); 0083 } 0084 0085 void NumberFieldWidget::setTextImpl(const QString& text_) { 0086 if(isSpinBox()) { 0087 if(text_.isEmpty()) { 0088 m_spinBox->clear(); 0089 return; 0090 } 0091 bool ok; 0092 int n = text_.toInt(&ok); 0093 if(ok) { 0094 // did just allow positive 0095 if(n < m_spinBox->minimum()+1) { 0096 m_spinBox->setMinimum(std::numeric_limits<int>::min()+1); 0097 } 0098 m_spinBox->setValue(n); 0099 } 0100 } else { 0101 m_lineEdit->setText(text_); 0102 } 0103 } 0104 0105 void NumberFieldWidget::clearImpl() { 0106 if(isSpinBox()) { 0107 m_spinBox->clear(); 0108 } else { 0109 m_lineEdit->clear(); 0110 } 0111 editMultiple(false); 0112 } 0113 0114 void NumberFieldWidget::updateFieldHook(Tellico::Data::FieldPtr, Tellico::Data::FieldPtr newField_) { 0115 bool wasLineEdit = !isSpinBox(); 0116 bool nowLineEdit = newField_->hasFlag(Data::Field::AllowMultiple); 0117 0118 if(wasLineEdit == nowLineEdit) { 0119 return; 0120 } 0121 0122 const int widgetIndex = layout()->indexOf(widget()); 0123 Q_ASSERT(widgetIndex > -1); 0124 0125 const QString value = text(); 0126 if(wasLineEdit && !nowLineEdit) { 0127 layout()->removeWidget(m_lineEdit); 0128 delete m_lineEdit; 0129 m_lineEdit = nullptr; 0130 initSpinBox(); 0131 } else if(!wasLineEdit && nowLineEdit) { 0132 layout()->removeWidget(m_spinBox); 0133 delete m_spinBox; 0134 m_spinBox = nullptr; 0135 initLineEdit(); 0136 } 0137 0138 static_cast<QBoxLayout*>(layout())->insertWidget(widgetIndex, widget(), 1 /*stretch*/); 0139 widget()->show(); 0140 setText(value); 0141 } 0142 0143 QWidget* NumberFieldWidget::widget() { 0144 if(isSpinBox()) { 0145 return m_spinBox; 0146 } 0147 return m_lineEdit; 0148 }