File indexing completed on 2025-01-05 03:51:06
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 1997-04-21 0007 * Description : A date selection widget. 0008 * 0009 * SPDX-FileCopyrightText: 2011-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * SPDX-FileCopyrightText: 1997 by Tim D. Gilman <tdgilman at best dot org> 0011 * SPDX-FileCopyrightText: 1998-2001 by Mirko Boehm <mirko at kde dot org> 0012 * SPDX-FileCopyrightText: 2007 by John Layt <john at layt dot net> 0013 * 0014 * SPDX-License-Identifier: GPL-2.0-or-later 0015 * 0016 * ============================================================ */ 0017 0018 #include "ddatepicker_p.h" 0019 0020 // Qt includes 0021 0022 #include <QFontDatabase> 0023 0024 // KDE includes 0025 0026 #include <klocalizedstring.h> 0027 0028 namespace Digikam 0029 { 0030 0031 DatePickerValidator::DatePickerValidator(DDatePicker* const parent) 0032 : QValidator(parent), 0033 m_picker (parent) 0034 { 0035 } 0036 0037 QValidator::State DatePickerValidator::validate(QString& text, int&) const 0038 { 0039 QLocale::FormatType formats[] = 0040 { 0041 QLocale::LongFormat, 0042 QLocale::ShortFormat, 0043 QLocale::NarrowFormat 0044 }; 0045 0046 QLocale locale = m_picker->locale(); 0047 0048 for (int i = 0 ; i < 3 ; ++i) 0049 { 0050 QDate tmp = locale.toDate(text, formats[i]); 0051 0052 if (tmp.isValid()) 0053 { 0054 return Acceptable; 0055 } 0056 } 0057 0058 return QValidator::Intermediate; 0059 } 0060 0061 // ------------------------------------------------------------------------------ 0062 0063 /** 0064 * NOTE: Week numbers are defined by ISO 8601 0065 * See https://en.wikipedia.org/wiki/Week#Week_numbering for details 0066 */ 0067 DatePickerYearSelector::DatePickerYearSelector(const QDate& currentDate, QWidget* const parent) 0068 : QLineEdit(parent), 0069 val (new QIntValidator(this)), 0070 result (0), 0071 oldDate (currentDate) 0072 { 0073 setFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont)); 0074 0075 setFrame(false); 0076 0077 /* 0078 TODO: Find a way to get that from QLocale 0079 val->setRange(calendar->year(calendar->earliestValidDate()), 0080 calendar->year(calendar->latestValidDate())); 0081 */ 0082 setValidator(val); 0083 0084 connect(this, &QLineEdit::returnPressed, 0085 this, &DatePickerYearSelector::yearEnteredSlot); 0086 } 0087 0088 void DatePickerYearSelector::yearEnteredSlot() 0089 { 0090 bool ok; 0091 int newYear; 0092 0093 // check if entered value is a number 0094 0095 newYear = text().toInt(&ok); 0096 0097 if (!ok) 0098 { 0099 QApplication::beep(); 0100 return; 0101 } 0102 0103 // check if new year will lead to a valid date 0104 0105 if (QDate(newYear, oldDate.month(), oldDate.day()).isValid()) 0106 { 0107 result = newYear; 0108 Q_EMIT closeMe(1); 0109 } 0110 else 0111 { 0112 QApplication::beep(); 0113 } 0114 } 0115 0116 int DatePickerYearSelector::year() const 0117 { 0118 return result; 0119 } 0120 0121 void DatePickerYearSelector::setYear(int year) 0122 { 0123 setText(QString::number(year)); 0124 } 0125 0126 // ------------------------------------------------------------------------------ 0127 0128 DDatePicker::Private::Private(DDatePicker* const qq) 0129 : q (qq), 0130 closeButton (nullptr), 0131 selectWeek (nullptr), 0132 todayButton (nullptr), 0133 navigationLayout (nullptr), 0134 yearForward (nullptr), 0135 yearBackward (nullptr), 0136 monthForward (nullptr), 0137 monthBackward (nullptr), 0138 selectMonth (nullptr), 0139 selectYear (nullptr), 0140 line (nullptr), 0141 val (nullptr), 0142 table (nullptr), 0143 fontsize (0) 0144 { 0145 } 0146 0147 void DDatePicker::Private::fillWeeksCombo() 0148 { 0149 /** 0150 * NOTE: every year can have a different number of weeks 0151 * it could be that we had 53,1..52 and now 1..53 which is the same number but different 0152 * so always fill with new values 0153 * We show all week numbers for all weeks between first day of year to last day of year 0154 * This of course can be a list like 53,1,2..52 0155 */ 0156 const QDate thisDate = q->date(); 0157 const int thisYear = thisDate.year(); 0158 QDate day(thisDate.year(), 1, 1); 0159 const QDate lastDayOfYear = QDate(thisDate.year() + 1, 1, 1).addDays(-1); 0160 0161 selectWeek->clear(); 0162 0163 // Starting from the first day in the year, loop through the year a week at a time 0164 // adding an entry to the week combo for each week in the year 0165 0166 for ( ; day.isValid() && (day <= lastDayOfYear) ; (day = day.addDays(7))) 0167 { 0168 // Get the ISO week number for the current day and what year that week is in 0169 // e.g. 1st day of this year may fall in week 53 of previous year 0170 0171 int weekYear = thisYear; 0172 const int week = day.weekNumber(&weekYear); 0173 QString weekString = i18n("Week %1", week); 0174 0175 // show that this is a week from a different year 0176 0177 if (weekYear != thisYear) 0178 { 0179 weekString += QLatin1Char('*'); 0180 } 0181 0182 // when the week is selected, go to the same weekday as the one 0183 // that is currently selected in the date table 0184 0185 QDate targetDate = day.addDays(thisDate.dayOfWeek() - day.dayOfWeek()); 0186 selectWeek->addItem(weekString, targetDate); 0187 0188 // make sure that the week of the lastDayOfYear is always inserted: in Chinese calendar 0189 // system, this is not always the case 0190 0191 if ( 0192 (day < lastDayOfYear) && 0193 (day.daysTo(lastDayOfYear) < 7) && 0194 (lastDayOfYear.weekNumber() != day.weekNumber()) 0195 ) 0196 { 0197 day = lastDayOfYear.addDays(-7); 0198 } 0199 } 0200 } 0201 0202 QDate DDatePicker::Private::validDateInYearMonth(int year, int month) 0203 { 0204 QDate newDate; 0205 0206 // Try to create a valid date in this year and month 0207 // First try the first of the month, then try last of month 0208 0209 if (QDate(year, month, 1).isValid()) 0210 { 0211 newDate = QDate(year, month, 1); 0212 } 0213 else if (QDate(year, month + 1, 1).isValid()) 0214 { 0215 newDate = QDate(year, month + 1, 1).addDays(-1); 0216 } 0217 else 0218 { 0219 newDate = QDate::fromJulianDay(0); 0220 } 0221 0222 return newDate; 0223 } 0224 0225 } // namespace Digikam 0226 0227 #include "moc_ddatepicker_p.cpp"