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 SearchFieldRangeDate::SearchFieldRangeDate(QObject* const parent, Type type) 0022 : SearchField (parent), 0023 m_firstTimeEdit (nullptr), 0024 m_firstDateEdit (nullptr), 0025 m_secondTimeEdit(nullptr), 0026 m_secondDateEdit(nullptr), 0027 m_type (type) 0028 { 0029 m_betweenLabel = new QLabel; 0030 } 0031 0032 void SearchFieldRangeDate::setupValueWidgets(QGridLayout* layout, int row, int column) 0033 { 0034 /* 0035 QHBoxLayout *hbox = new QHBoxLayout; 0036 layout->addLayout(hbox, row, column, 1, 3); 0037 */ 0038 m_firstDateEdit = new DDateEdit; 0039 m_secondDateEdit = new DDateEdit; 0040 0041 if (m_type == DateOnly) 0042 { 0043 layout->addWidget(m_firstDateEdit, row, column); 0044 layout->addWidget(m_betweenLabel, row, column + 1, Qt::AlignHCenter); 0045 layout->addWidget(m_secondDateEdit, row, column + 2); 0046 } 0047 else 0048 { 0049 QHBoxLayout* const hbox1 = new QHBoxLayout; 0050 QHBoxLayout* const hbox2 = new QHBoxLayout; 0051 0052 m_firstTimeEdit = new QTimeEdit; 0053 m_secondTimeEdit = new QTimeEdit; 0054 0055 hbox1->addWidget(m_firstDateEdit); 0056 hbox1->addWidget(m_firstTimeEdit); 0057 hbox2->addWidget(m_secondDateEdit); 0058 hbox2->addWidget(m_secondTimeEdit); 0059 0060 layout->addLayout(hbox1, row, column); 0061 layout->addWidget(m_betweenLabel, row, column + 1, Qt::AlignHCenter); 0062 layout->addLayout(hbox2, row, column + 2); 0063 } 0064 0065 connect(m_firstDateEdit, SIGNAL(dateChanged(QDate)), 0066 this, SLOT(valueChanged())); 0067 0068 connect(m_secondDateEdit, SIGNAL(dateChanged(QDate)), 0069 this, SLOT(valueChanged())); 0070 } 0071 0072 void SearchFieldRangeDate::setBetweenText(const QString& between) 0073 { 0074 m_betweenLabel->setText(between); 0075 } 0076 0077 void SearchFieldRangeDate::read(SearchXmlCachingReader& reader) 0078 { 0079 SearchXml::Relation relation = reader.fieldRelation(); 0080 0081 if ((relation == SearchXml::Interval) || (relation == SearchXml::IntervalOpen)) 0082 { 0083 QList<QDateTime> dates = reader.valueToDateTimeList(); 0084 0085 if (dates.size() != 2) 0086 { 0087 return; 0088 } 0089 0090 if (m_type == DateTime) 0091 { 0092 m_firstDateEdit->setDate(dates.first().date()); 0093 m_firstTimeEdit->setTime(dates.first().time()); 0094 m_secondDateEdit->setDate(dates.last().date()); 0095 m_secondTimeEdit->setTime(dates.last().time()); 0096 } 0097 else 0098 { 0099 if (relation == SearchXml::Interval) 0100 { 0101 dates.last() = dates.last().addDays(-1); 0102 } 0103 0104 m_firstDateEdit->setDate(dates.first().date()); 0105 m_secondDateEdit->setDate(dates.last().date()); 0106 } 0107 } 0108 else 0109 { 0110 QDateTime dt = reader.valueToDateTime(); 0111 0112 if (m_type == DateTime) 0113 { 0114 if (relation == SearchXml::Equal) 0115 { 0116 m_firstDateEdit->setDate(dt.date()); 0117 m_firstTimeEdit->setTime(dt.time()); 0118 m_secondDateEdit->setDate(dt.date()); 0119 m_secondTimeEdit->setTime(dt.time()); 0120 } 0121 else if (relation == SearchXml::GreaterThanOrEqual || relation == SearchXml::GreaterThan) 0122 { 0123 m_firstDateEdit->setDate(dt.date()); 0124 m_firstTimeEdit->setTime(dt.time()); 0125 } 0126 0127 { 0128 m_secondDateEdit->setDate(dt.date()); 0129 m_secondTimeEdit->setTime(dt.time()); 0130 } 0131 } 0132 else 0133 { 0134 // In DateOnly mode, we always assume dealing with the beginning of the day, QTime(0,0,0). 0135 // In the UI, we show the date only (including the whole day). 0136 // The difference between ...Than and ...ThanOrEqual is only one second, ignored. 0137 0138 if (relation == SearchXml::Equal) 0139 { 0140 m_firstDateEdit->setDate(dt.date()); 0141 m_secondDateEdit->setDate(dt.date()); 0142 } 0143 else if (relation == SearchXml::GreaterThanOrEqual || relation == SearchXml::GreaterThan) 0144 { 0145 m_firstDateEdit->setDate(dt.date()); 0146 } 0147 else if (relation == SearchXml::LessThanOrEqual || relation == SearchXml::LessThan) 0148 { 0149 dt = dt.addDays(-1); 0150 m_secondDateEdit->setDate(dt.date()); 0151 } 0152 } 0153 } 0154 0155 valueChanged(); 0156 } 0157 0158 void SearchFieldRangeDate::write(SearchXmlWriter& writer) 0159 { 0160 if (m_firstDateEdit->date().isValid() && m_secondDateEdit->date().isValid()) 0161 { 0162 QDateTime firstDate = startOfDay(m_firstDateEdit->date()); 0163 0164 if (m_type == DateTime) 0165 { 0166 firstDate.setTime(m_firstTimeEdit->time()); 0167 } 0168 0169 QDateTime secondDate = startOfDay(m_secondDateEdit->date()); 0170 0171 if (m_type == DateTime) 0172 { 0173 secondDate.setTime(m_secondTimeEdit->time()); 0174 } 0175 0176 if (firstDate == secondDate) 0177 { 0178 writer.writeField(m_name, SearchXml::Equal); 0179 writer.writeValue(firstDate); 0180 writer.finishField(); 0181 } 0182 else 0183 { 0184 if (m_type == DateOnly) 0185 { 0186 secondDate = secondDate.addDays(1); 0187 } 0188 0189 writer.writeField(m_name, SearchXml::Interval); 0190 writer.writeValue(QList<QDateTime>() << firstDate << secondDate); 0191 writer.finishField(); 0192 } 0193 } 0194 else 0195 { 0196 QDate date = m_firstDateEdit->date(); 0197 0198 if (date.isValid()) 0199 { 0200 writer.writeField(m_name, SearchXml::GreaterThanOrEqual); 0201 QDateTime dt = startOfDay(date); 0202 0203 if (m_type == DateTime) 0204 { 0205 dt.setTime(m_firstTimeEdit->time()); 0206 } 0207 0208 writer.writeValue(dt); 0209 writer.finishField(); 0210 } 0211 0212 date = m_secondDateEdit->date(); 0213 0214 if (date.isValid()) 0215 { 0216 writer.writeField(m_name, SearchXml::LessThan); 0217 QDateTime dt = startOfDay(date); 0218 0219 if (m_type == DateTime) 0220 { 0221 dt.setTime(m_secondTimeEdit->time()); 0222 } 0223 else 0224 { 0225 dt = dt.addDays(1); // include whole day 0226 } 0227 0228 writer.writeValue(dt); 0229 writer.finishField(); 0230 } 0231 } 0232 } 0233 0234 void SearchFieldRangeDate::reset() 0235 { 0236 m_firstDateEdit->setDate(QDate()); 0237 0238 if (m_type == DateTime) 0239 { 0240 m_firstTimeEdit->setTime(QTime(0, 0, 0, 0)); 0241 } 0242 0243 m_secondDateEdit->setDate(QDate()); 0244 0245 if (m_type == DateTime) 0246 { 0247 m_secondTimeEdit->setTime(QTime(0, 0, 0, 0)); 0248 } 0249 0250 valueChanged(); 0251 } 0252 0253 void SearchFieldRangeDate::setBoundary(const QDateTime& min, const QDateTime& max) 0254 { 0255 // something here? 0256 0257 Q_UNUSED(min); 0258 Q_UNUSED(max); 0259 } 0260 0261 void SearchFieldRangeDate::setValueWidgetsVisible(bool visible) 0262 { 0263 m_firstDateEdit->setVisible(visible); 0264 0265 if (m_firstTimeEdit) 0266 { 0267 m_firstTimeEdit->setVisible(visible); 0268 } 0269 0270 m_secondDateEdit->setVisible(visible); 0271 0272 if (m_secondTimeEdit) 0273 { 0274 m_secondTimeEdit->setVisible(visible); 0275 } 0276 0277 m_betweenLabel->setVisible(visible); 0278 } 0279 0280 QList<QRect> SearchFieldRangeDate::valueWidgetRects() const 0281 { 0282 QList<QRect> rects; 0283 rects << m_firstDateEdit->geometry(); 0284 0285 if (m_firstTimeEdit) 0286 { 0287 rects << m_firstTimeEdit->geometry(); 0288 } 0289 0290 rects << m_secondDateEdit->geometry(); 0291 0292 if (m_secondTimeEdit) 0293 { 0294 rects << m_secondTimeEdit->geometry(); 0295 } 0296 0297 return rects; 0298 } 0299 0300 void SearchFieldRangeDate::valueChanged() 0301 { 0302 setValidValueState(m_firstDateEdit->date().isValid() || m_secondDateEdit->date().isValid()); 0303 } 0304 0305 //----------------------------------------------------------------------------- 0306 0307 SearchFieldRangeTime::SearchFieldRangeTime(QObject* const parent) 0308 : SearchField (parent), 0309 m_firstTimeEdit (nullptr), 0310 m_secondTimeEdit(nullptr) 0311 { 0312 m_betweenLabel = new QLabel; 0313 } 0314 0315 void SearchFieldRangeTime::setupValueWidgets(QGridLayout* layout, int row, int column) 0316 { 0317 m_firstTimeEdit = new QTimeEdit; 0318 m_secondTimeEdit = new QTimeEdit; 0319 0320 layout->addWidget(m_firstTimeEdit, row, column); 0321 layout->addWidget(m_betweenLabel, row, column + 1, Qt::AlignHCenter); 0322 layout->addWidget(m_secondTimeEdit, row, column + 2); 0323 0324 connect(m_firstTimeEdit, SIGNAL(timeChanged(QTime)), 0325 this, SLOT(valueChanged())); 0326 0327 connect(m_secondTimeEdit, SIGNAL(timeChanged(QTime)), 0328 this, SLOT(valueChanged())); 0329 } 0330 0331 void SearchFieldRangeTime::setBetweenText(const QString& between) 0332 { 0333 m_betweenLabel->setText(between); 0334 } 0335 0336 void SearchFieldRangeTime::read(SearchXmlCachingReader& reader) 0337 { 0338 SearchXml::Relation relation = reader.fieldRelation(); 0339 0340 if (relation == SearchXml::Interval) 0341 { 0342 QList<QDateTime> dates = reader.valueToDateTimeList(); 0343 0344 if (dates.size() != 2) 0345 { 0346 return; 0347 } 0348 0349 m_firstTimeEdit->setTime(dates.first().time()); 0350 m_secondTimeEdit->setTime(dates.last().time()); 0351 } 0352 0353 valueChanged(); 0354 } 0355 0356 void SearchFieldRangeTime::write(SearchXmlWriter& writer) 0357 { 0358 if (m_firstTimeEdit->time().isValid() && m_secondTimeEdit->time().isValid()) 0359 { 0360 int time = m_firstTimeEdit->time().hour() + 0361 m_firstTimeEdit->time().minute() + 0362 m_secondTimeEdit->time().hour() + 0363 m_secondTimeEdit->time().minute(); 0364 0365 if (time > 0) 0366 { 0367 QDateTime firstDate = QDateTime::currentDateTime(); 0368 firstDate.setTime(m_firstTimeEdit->time()); 0369 0370 QDateTime secondDate = QDateTime::currentDateTime(); 0371 secondDate.setTime(m_secondTimeEdit->time()); 0372 0373 writer.writeField(m_name, SearchXml::Interval); 0374 writer.writeValue(QList<QDateTime>() << firstDate << secondDate); 0375 writer.finishField(); 0376 } 0377 } 0378 } 0379 0380 void SearchFieldRangeTime::reset() 0381 { 0382 m_firstTimeEdit->setTime(QTime(0, 0, 0, 0)); 0383 m_secondTimeEdit->setTime(QTime(0, 0, 0, 0)); 0384 0385 valueChanged(); 0386 } 0387 0388 void SearchFieldRangeTime::setBoundary(const QTime& min, const QTime& max) 0389 { 0390 // something here? 0391 0392 Q_UNUSED(min); 0393 Q_UNUSED(max); 0394 } 0395 0396 void SearchFieldRangeTime::setValueWidgetsVisible(bool visible) 0397 { 0398 m_firstTimeEdit->setVisible(visible); 0399 m_secondTimeEdit->setVisible(visible); 0400 m_betweenLabel->setVisible(visible); 0401 } 0402 0403 QList<QRect> SearchFieldRangeTime::valueWidgetRects() const 0404 { 0405 QList<QRect> rects; 0406 rects << m_firstTimeEdit->geometry(); 0407 rects << m_secondTimeEdit->geometry(); 0408 0409 return rects; 0410 } 0411 0412 void SearchFieldRangeTime::valueChanged() 0413 { 0414 int time = 0; 0415 bool validTime = (m_firstTimeEdit->time().isValid() && 0416 m_secondTimeEdit->time().isValid()); 0417 0418 if (validTime) 0419 { 0420 QTime secondTime = m_secondTimeEdit->time(); 0421 0422 if (m_firstTimeEdit->time() >= secondTime) 0423 { 0424 secondTime = m_firstTimeEdit->time(); 0425 } 0426 0427 m_secondTimeEdit->setTime(QTime(secondTime.hour(), 0428 secondTime.minute(), 59)); 0429 0430 time = m_firstTimeEdit->time().hour() + 0431 m_firstTimeEdit->time().minute() + 0432 m_secondTimeEdit->time().hour() + 0433 m_secondTimeEdit->time().minute(); 0434 } 0435 0436 setValidValueState(validTime && (time > 0)); 0437 } 0438 0439 } // namespace Digikam