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 SearchFieldRangeInt::SearchFieldRangeInt(QObject* const parent) 0022 : SearchField (parent), 0023 m_min (0), 0024 m_max (100), 0025 m_reciprocal (false), 0026 m_firstBox (nullptr), 0027 m_secondBox (nullptr) 0028 { 0029 m_betweenLabel = new QLabel; 0030 m_firstBox = new CustomStepsIntSpinBox; 0031 m_secondBox = new CustomStepsIntSpinBox; 0032 } 0033 0034 void SearchFieldRangeInt::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 hbox->addWidget(m_firstBox); 0044 hbox->addWidget(m_betweenLabel); 0045 hbox->addWidget(m_secondBox); 0046 hbox->addStretch(1); 0047 */ 0048 layout->addWidget(m_firstBox, row, column); 0049 layout->addWidget(m_betweenLabel, row, column + 1, Qt::AlignHCenter); 0050 layout->addWidget(m_secondBox, row, column + 2); 0051 0052 connect(m_firstBox, SIGNAL(valueChanged(int)), 0053 this, SLOT(valueChanged())); 0054 0055 connect(m_secondBox, SIGNAL(valueChanged(int)), 0056 this, SLOT(valueChanged())); 0057 } 0058 0059 void SearchFieldRangeInt::read(SearchXmlCachingReader& reader) 0060 { 0061 SearchXml::Relation relation = reader.fieldRelation(); 0062 0063 if (m_reciprocal) 0064 { 0065 switch (relation) 0066 { 0067 case SearchXml::LessThanOrEqual: 0068 case SearchXml::LessThan: 0069 m_firstBox->setFractionMagicValue(reader.valueToDouble()); 0070 break; 0071 0072 case SearchXml::GreaterThanOrEqual: 0073 case SearchXml::GreaterThan: 0074 m_secondBox->setFractionMagicValue(reader.valueToDouble()); 0075 break; 0076 0077 case SearchXml::Equal: 0078 m_firstBox->setFractionMagicValue(reader.valueToDouble()); 0079 m_secondBox->setFractionMagicValue(reader.valueToDouble()); 0080 break; 0081 0082 case SearchXml::Interval: 0083 case SearchXml::IntervalOpen: 0084 { 0085 QList<double> list = reader.valueToDoubleList(); 0086 0087 if (list.size() != 2) 0088 { 0089 return; 0090 } 0091 0092 m_secondBox->setFractionMagicValue(list.first()); 0093 m_firstBox->setFractionMagicValue(list.last()); 0094 break; 0095 } 0096 0097 default: 0098 break; 0099 } 0100 } 0101 else 0102 { 0103 switch (relation) 0104 { 0105 case SearchXml::GreaterThanOrEqual: 0106 m_firstBox->setValue(reader.valueToInt()); 0107 break; 0108 0109 case SearchXml::GreaterThan: 0110 m_firstBox->setValue(reader.valueToInt() - 1); 0111 break; 0112 0113 case SearchXml::LessThanOrEqual: 0114 m_secondBox->setValue(reader.valueToInt()); 0115 break; 0116 0117 case SearchXml::LessThan: 0118 m_secondBox->setValue(reader.valueToInt() + 1); 0119 break; 0120 0121 case SearchXml::Equal: 0122 m_firstBox->setValue(reader.valueToInt()); 0123 m_secondBox->setValue(reader.valueToInt()); 0124 break; 0125 0126 case SearchXml::Interval: 0127 case SearchXml::IntervalOpen: 0128 { 0129 QList<int> list = reader.valueToIntList(); 0130 0131 if (list.size() != 2) 0132 { 0133 return; 0134 } 0135 0136 m_firstBox->setValue(list.first()); 0137 m_secondBox->setValue(list.last()); 0138 break; 0139 } 0140 0141 default: 0142 break; 0143 } 0144 } 0145 } 0146 0147 void SearchFieldRangeInt::write(SearchXmlWriter& writer) 0148 { 0149 if ((m_firstBox->value() != m_firstBox->minimum()) && 0150 (m_secondBox->value() != m_secondBox->minimum())) 0151 { 0152 if (m_firstBox->value() != m_secondBox->value()) 0153 { 0154 writer.writeField(m_name, SearchXml::Interval); 0155 0156 if (m_reciprocal) 0157 { 0158 writer.writeValue(QList<float>() << m_secondBox->fractionMagicValue() << m_firstBox->fractionMagicValue()); 0159 } 0160 else 0161 { 0162 writer.writeValue(QList<int>() << m_firstBox->value() << m_secondBox->value()); 0163 } 0164 0165 writer.finishField(); 0166 } 0167 else 0168 { 0169 /** 0170 * @todo : This condition is never met. 0171 * Right value is either displayed empty (minimum, greater than left) 0172 * or one step larger than left 0173 */ 0174 0175 writer.writeField(m_name, SearchXml::Equal); 0176 0177 if (m_reciprocal) 0178 { 0179 writer.writeValue(m_firstBox->fractionMagicValue()); 0180 } 0181 else 0182 { 0183 writer.writeValue(m_firstBox->value()); 0184 } 0185 0186 writer.finishField(); 0187 } 0188 } 0189 else 0190 { 0191 if (m_firstBox->value() != m_firstBox->minimum()) 0192 { 0193 if (m_reciprocal) 0194 { 0195 writer.writeField(m_name, SearchXml::LessThanOrEqual); 0196 writer.writeValue(m_firstBox->fractionMagicValue()); 0197 } 0198 else 0199 { 0200 writer.writeField(m_name, SearchXml::GreaterThanOrEqual); 0201 writer.writeValue(m_firstBox->value()); 0202 } 0203 0204 writer.finishField(); 0205 } 0206 0207 if (m_secondBox->value() != m_secondBox->minimum()) 0208 { 0209 if (m_reciprocal) 0210 { 0211 writer.writeField(m_name, SearchXml::GreaterThanOrEqual); 0212 writer.writeValue(m_secondBox->fractionMagicValue()); 0213 } 0214 else 0215 { 0216 writer.writeField(m_name, SearchXml::LessThanOrEqual); 0217 writer.writeValue(m_secondBox->value()); 0218 } 0219 0220 writer.finishField(); 0221 } 0222 } 0223 } 0224 0225 void SearchFieldRangeInt::setBetweenText(const QString& text) 0226 { 0227 m_betweenLabel->setText(text); 0228 } 0229 0230 void SearchFieldRangeInt::setNumberPrefixAndSuffix(const QString& prefix, const QString& suffix) 0231 { 0232 m_firstBox->setPrefix(prefix); 0233 m_secondBox->setPrefix(prefix); 0234 m_firstBox->setSuffix(suffix); 0235 m_secondBox->setSuffix(suffix); 0236 } 0237 0238 void SearchFieldRangeInt::setBoundary(int min, int max, int step) 0239 { 0240 if (m_reciprocal) 0241 { 0242 m_min = max; 0243 m_max = min; 0244 } 0245 else 0246 { 0247 m_min = min; 0248 m_max = max; 0249 } 0250 0251 m_firstBox->setRange(m_min, m_max); 0252 m_firstBox->setSingleStep(step); 0253 m_firstBox->setValue(m_min); 0254 0255 m_secondBox->setRange(m_min, m_max); 0256 m_secondBox->setSingleStep(step); 0257 m_secondBox->setValue(m_min); 0258 } 0259 0260 void SearchFieldRangeInt::enableFractionMagic(const QString& prefix) 0261 { 0262 m_reciprocal = true; 0263 0264 m_firstBox->enableFractionMagic(prefix); 0265 m_firstBox->setInvertStepping(true); 0266 0267 m_secondBox->enableFractionMagic(prefix); 0268 m_secondBox->setInvertStepping(true); 0269 } 0270 0271 void SearchFieldRangeInt::setSuggestedValues(const QList<int>& values) 0272 { 0273 m_firstBox->setSuggestedValues(values); 0274 m_secondBox->setSuggestedValues(values); 0275 } 0276 0277 void SearchFieldRangeInt::setSuggestedInitialValue(int value) 0278 { 0279 m_firstBox->setSuggestedInitialValue(value); 0280 m_secondBox->setSuggestedInitialValue(value); 0281 } 0282 0283 void SearchFieldRangeInt::setSingleSteps(int smaller, int larger) 0284 { 0285 m_firstBox->setSingleSteps(smaller, larger); 0286 m_secondBox->setSingleSteps(smaller, larger); 0287 } 0288 0289 void SearchFieldRangeInt::setInvertStepping(bool invert) 0290 { 0291 m_firstBox->setInvertStepping(invert); 0292 m_secondBox->setInvertStepping(invert); 0293 } 0294 0295 void SearchFieldRangeInt::valueChanged() 0296 { 0297 bool validValue = false; 0298 0299 if (m_reciprocal) 0300 { 0301 bool firstAtMinimum = (m_firstBox->value() == m_firstBox->minimum()); 0302 bool secondAtMinimum = (m_secondBox->value() == m_secondBox->minimum()); 0303 0304 if (!secondAtMinimum) 0305 { 0306 m_firstBox->setRange(m_secondBox->value() - 1, m_max); 0307 validValue = true; 0308 } 0309 0310 if (!firstAtMinimum) 0311 { 0312 m_secondBox->setRange(m_min - 1, m_firstBox->value()); 0313 0314 if (secondAtMinimum) 0315 { 0316 m_firstBox->setRange(m_min, m_max); 0317 m_secondBox->setValue(m_secondBox->minimum()); 0318 } 0319 0320 validValue = true; 0321 } 0322 0323 if (firstAtMinimum && secondAtMinimum) 0324 { 0325 m_firstBox->setRange(m_min, m_max); 0326 m_secondBox->setRange(m_min, m_max); 0327 } 0328 } 0329 else 0330 { 0331 bool firstAtMinimum = (m_firstBox->value() == m_firstBox->minimum()); 0332 bool secondAtMinimum = (m_secondBox->value() == m_secondBox->minimum()); 0333 0334 if (!secondAtMinimum) 0335 { 0336 m_firstBox->setRange(m_min, m_secondBox->value()); 0337 validValue = true; 0338 } 0339 0340 if (!firstAtMinimum) 0341 { 0342 m_secondBox->setRange(m_firstBox->value() - 1, m_max); 0343 0344 if (secondAtMinimum) 0345 { 0346 m_firstBox->setRange(m_min, m_max); 0347 m_secondBox->setValue(m_secondBox->minimum()); 0348 } 0349 0350 validValue = true; 0351 } 0352 0353 if (firstAtMinimum && secondAtMinimum) 0354 { 0355 m_firstBox->setRange(m_min, m_max); 0356 m_secondBox->setRange(m_min, m_max); 0357 } 0358 } 0359 0360 setValidValueState(validValue); 0361 } 0362 0363 void SearchFieldRangeInt::reset() 0364 { 0365 m_firstBox->setRange(m_min, m_max); 0366 m_secondBox->setRange(m_min, m_max); 0367 m_firstBox->reset(); 0368 m_secondBox->reset(); 0369 } 0370 0371 void SearchFieldRangeInt::setValueWidgetsVisible(bool visible) 0372 { 0373 m_firstBox->setVisible(visible); 0374 m_secondBox->setVisible(visible); 0375 m_betweenLabel->setVisible(visible); 0376 } 0377 0378 QList<QRect> SearchFieldRangeInt::valueWidgetRects() const 0379 { 0380 QList<QRect> rects; 0381 rects << m_firstBox->geometry(); 0382 rects << m_secondBox->geometry(); 0383 0384 return rects; 0385 } 0386 0387 } // namespace Digikam