File indexing completed on 2025-01-05 04:00:05

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2008-01-20
0007  * Description : User interface for searches
0008  *
0009  * SPDX-FileCopyrightText: 2008-2012 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0010  * SPDX-FileCopyrightText: 2011-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "searchfields_p.h"
0017 
0018 namespace Digikam
0019 {
0020 
0021 SearchFieldRangeDouble::SearchFieldRangeDouble(QObject* const parent)
0022     : SearchField(parent),
0023       m_min      (0),
0024       m_max      (100),
0025       m_factor   (1),
0026       m_firstBox (nullptr),
0027       m_secondBox(nullptr)
0028 {
0029     m_betweenLabel = new QLabel;
0030     m_firstBox     = new CustomStepsDoubleSpinBox;
0031     m_secondBox    = new CustomStepsDoubleSpinBox;
0032 }
0033 
0034 void SearchFieldRangeDouble::setupValueWidgets(QGridLayout* layout, int row, int column)
0035 {
0036 /*
0037     QHBoxLayout *hbox = new QHBoxLayout;
0038     layout->addLayout(hbox, row, column);
0039 */
0040     m_firstBox->setSpecialValueText(QLatin1String(" "));
0041     m_secondBox->setSpecialValueText(QLatin1String(" "));
0042 
0043 /*
0044     hbox->addWidget(m_firstBox);
0045     hbox->addWidget(m_betweenLabel);
0046     hbox->addWidget(m_secondBox);
0047     hbox->addStretch(1);
0048 */
0049     layout->addWidget(m_firstBox,     row, column);
0050     layout->addWidget(m_betweenLabel, row, column + 1, Qt::AlignHCenter);
0051     layout->addWidget(m_secondBox,    row, column + 2);
0052 
0053     connect(m_firstBox, SIGNAL(valueChanged(double)),
0054             this, SLOT(valueChanged()));
0055 
0056     connect(m_secondBox, SIGNAL(valueChanged(double)),
0057             this, SLOT(valueChanged()));
0058 }
0059 
0060 void SearchFieldRangeDouble::read(SearchXmlCachingReader& reader)
0061 {
0062     SearchXml::Relation relation = reader.fieldRelation();
0063 
0064     if      ((relation == SearchXml::GreaterThanOrEqual) || (relation == SearchXml::GreaterThan))
0065     {
0066         m_firstBox->setValue(reader.valueToDouble() / m_factor);
0067     }
0068     else if ((relation == SearchXml::LessThanOrEqual) || (relation == SearchXml::LessThan))
0069     {
0070         m_secondBox->setValue(reader.valueToDouble() / m_factor);
0071     }
0072     else if ((relation == SearchXml::Interval) || (relation == SearchXml::IntervalOpen))
0073     {
0074         QList<double> list = reader.valueToDoubleList();
0075 
0076         if (list.size() != 2)
0077         {
0078             return;
0079         }
0080 
0081         m_firstBox->setValue(list.first() / m_factor);
0082         m_secondBox->setValue(list.last() / m_factor);
0083     }
0084 }
0085 
0086 void SearchFieldRangeDouble::write(SearchXmlWriter& writer)
0087 {
0088     if ((m_firstBox->value() != m_firstBox->minimum()) && (m_secondBox->value() != m_secondBox->minimum()))
0089     {
0090         if (m_firstBox->value() != m_secondBox->value())
0091         {
0092             writer.writeField(m_name, SearchXml::Interval);
0093             writer.writeValue(QList<double>() << (m_firstBox->value() * m_factor) << (m_secondBox->value() * m_factor));
0094             writer.finishField();
0095         }
0096         else
0097         {
0098             // TODO: See SearchFieldRangeInt
0099 
0100             writer.writeField(m_name, SearchXml::Equal);
0101             writer.writeValue(m_firstBox->value() * m_factor);
0102             writer.finishField();
0103         }
0104     }
0105     else
0106     {
0107         if (m_firstBox->value() != m_firstBox->minimum())
0108         {
0109             writer.writeField(m_name, SearchXml::GreaterThanOrEqual);
0110             writer.writeValue(m_firstBox->value() * m_factor);
0111             writer.finishField();
0112         }
0113 
0114         if (m_secondBox->value() != m_secondBox->minimum())
0115         {
0116             writer.writeField(m_name, SearchXml::LessThanOrEqual);
0117             writer.writeValue(m_secondBox->value() * m_factor);
0118             writer.finishField();
0119         }
0120     }
0121 }
0122 
0123 void SearchFieldRangeDouble::setBetweenText(const QString& text)
0124 {
0125     m_betweenLabel->setText(text);
0126 }
0127 
0128 void SearchFieldRangeDouble::setNoValueText(const QString& text)
0129 {
0130     m_firstBox->setSpecialValueText(text);
0131     m_secondBox->setSpecialValueText(text);
0132 }
0133 
0134 void SearchFieldRangeDouble::setNumberPrefixAndSuffix(const QString& prefix, const QString& suffix)
0135 {
0136     m_firstBox->setPrefix(prefix);
0137     m_secondBox->setPrefix(prefix);
0138     m_firstBox->setSuffix(suffix);
0139     m_secondBox->setSuffix(suffix);
0140 }
0141 
0142 void SearchFieldRangeDouble::setBoundary(double min, double max, int decimals, double step)
0143 {
0144     m_min = min;
0145     m_max = max;
0146 
0147     m_firstBox->setRange(min, max);
0148     m_firstBox->setSingleStep(step);
0149     m_firstBox->setDecimals(decimals);
0150     m_firstBox->setValue(min);
0151 
0152     m_secondBox->setRange(min, max);
0153     m_secondBox->setSingleStep(step);
0154     m_secondBox->setDecimals(decimals);
0155     m_secondBox->setValue(min);
0156 }
0157 
0158 void SearchFieldRangeDouble::setFactor(double factor)
0159 {
0160     m_factor = factor;
0161 }
0162 
0163 void SearchFieldRangeDouble::setSuggestedValues(const QList<double>& values)
0164 {
0165     m_firstBox->setSuggestedValues(values);
0166     m_secondBox->setSuggestedValues(values);
0167 }
0168 
0169 void SearchFieldRangeDouble::setSuggestedInitialValue(double value)
0170 {
0171     m_firstBox->setSuggestedInitialValue(value);
0172     m_secondBox->setSuggestedInitialValue(value);
0173 }
0174 
0175 void SearchFieldRangeDouble::setSingleSteps(double smaller, double larger)
0176 {
0177     m_firstBox->setSingleSteps(smaller, larger);
0178     m_secondBox->setSingleSteps(smaller, larger);
0179 }
0180 
0181 void SearchFieldRangeDouble::setInvertStepping(bool invert)
0182 {
0183     m_firstBox->setInvertStepping(invert);
0184     m_secondBox->setInvertStepping(invert);
0185 }
0186 
0187 void SearchFieldRangeDouble::valueChanged()
0188 {
0189     bool validValue      = false;
0190     bool firstAtMinimum  = (m_firstBox->value()  == m_firstBox->minimum());
0191     bool secondAtMinimum = (m_secondBox->value() == m_secondBox->minimum());
0192 
0193     if (!secondAtMinimum)
0194     {
0195         m_firstBox->setRange(m_min, m_secondBox->value());
0196         validValue = true;
0197     }
0198 
0199     if (!firstAtMinimum)
0200     {
0201         m_secondBox->setRange(m_firstBox->value() - 0.1, m_max);
0202 
0203         if (secondAtMinimum)
0204         {
0205             m_firstBox->setRange(m_min, m_max);
0206             m_secondBox->setValue(m_secondBox->minimum());
0207         }
0208 
0209         validValue = true;
0210     }
0211 
0212     if (firstAtMinimum && secondAtMinimum)
0213     {
0214         m_firstBox->setRange(m_min, m_max);
0215         m_secondBox->setRange(m_min, m_max);
0216     }
0217 
0218     setValidValueState(validValue);
0219 }
0220 
0221 void SearchFieldRangeDouble::reset()
0222 {
0223     m_firstBox->setRange(m_min, m_max);
0224     m_secondBox->setRange(m_min, m_max);
0225     m_firstBox->reset();
0226     m_secondBox->reset();
0227 }
0228 
0229 void SearchFieldRangeDouble::setValueWidgetsVisible(bool visible)
0230 {
0231     m_firstBox->setVisible(visible);
0232     m_secondBox->setVisible(visible);
0233     m_betweenLabel->setVisible(visible);
0234 }
0235 
0236 QList<QRect> SearchFieldRangeDouble::valueWidgetRects() const
0237 {
0238     QList<QRect> rects;
0239     rects << m_firstBox->geometry();
0240     rects << m_secondBox->geometry();
0241 
0242     return rects;
0243 }
0244 
0245 } // namespace Digikam