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 }