File indexing completed on 2024-05-12 05:21:22
0001 /* 0002 This file is part of KOrganizer. 0003 SPDX-FileCopyrightText: 2002 Cornelius Schumacher <schumacher@kde.org> 0004 SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com> 0005 0006 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net> 0007 SPDX-FileContributor: Sergio Martins <sergio@kdab.com> 0008 0009 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 0010 */ 0011 0012 #include "datenavigator.h" 0013 #include "koglobals.h" 0014 #include "korganizer_debug.h" 0015 0016 DateNavigator::DateNavigator(QObject *parent) 0017 : QObject(parent) 0018 { 0019 mSelectedDates.append(QDate::currentDate()); 0020 } 0021 0022 DateNavigator::~DateNavigator() = default; 0023 0024 KCalendarCore::DateList DateNavigator::selectedDates() const 0025 { 0026 return mSelectedDates; 0027 } 0028 0029 int DateNavigator::datesCount() const 0030 { 0031 return mSelectedDates.count(); 0032 } 0033 0034 void DateNavigator::selectDates(const KCalendarCore::DateList &dateList, QDate preferredMonth) 0035 { 0036 if (!dateList.isEmpty()) { 0037 mSelectedDates = dateList; 0038 emitSelected(preferredMonth); 0039 } 0040 } 0041 0042 void DateNavigator::selectDate(QDate date) 0043 { 0044 if (!date.isValid()) { 0045 qCDebug(KORGANIZER_LOG) << "an invalid date was passed as a parameter!"; 0046 date = QDate::currentDate(); 0047 } 0048 mSelectedDates.clear(); 0049 mSelectedDates.append(date); 0050 0051 emitSelected(); 0052 } 0053 0054 void DateNavigator::selectDates(int count) 0055 { 0056 count = qMin(count, static_cast<int>(MAX_SELECTABLE_DAYS)); 0057 selectDates(mSelectedDates.first(), count); 0058 } 0059 0060 void DateNavigator::selectDates(const QDate &d, int count, const QDate &preferredMonth) 0061 { 0062 KCalendarCore::DateList dates; 0063 dates.reserve(count); 0064 0065 for (int i = 0; i < count; ++i) { 0066 dates.append(d.addDays(i)); 0067 } 0068 0069 mSelectedDates = dates; 0070 emitSelected(preferredMonth); 0071 } 0072 0073 void DateNavigator::selectWeekByDay(int weekDay, QDate d, QDate preferredMonth) 0074 { 0075 const int dateCount = mSelectedDates.count(); 0076 const bool weekStart = (weekDay == KOGlobals::self()->firstDayOfWeek()); 0077 if (weekStart && dateCount == 7) { 0078 selectWeek(d, preferredMonth); 0079 } else { 0080 selectDates(d, dateCount, preferredMonth); 0081 } 0082 } 0083 0084 void DateNavigator::selectWeek() 0085 { 0086 selectWeek(mSelectedDates.first()); 0087 } 0088 0089 void DateNavigator::selectWeek(const QDate &d, const QDate &preferredMonth) 0090 { 0091 const int dayOfWeek = d.dayOfWeek(); 0092 const int weekStart = KOGlobals::self()->firstDayOfWeek(); 0093 0094 QDate firstDate = d.addDays(weekStart - dayOfWeek); 0095 0096 if (weekStart != 1 && dayOfWeek < weekStart) { 0097 firstDate = firstDate.addDays(-7); 0098 } 0099 0100 selectDates(firstDate, 7, preferredMonth); 0101 } 0102 0103 void DateNavigator::selectWorkWeek() 0104 { 0105 selectWorkWeek(mSelectedDates.first()); 0106 } 0107 0108 void DateNavigator::selectWorkWeek(QDate d) 0109 { 0110 const int weekStart = KOGlobals::self()->firstDayOfWeek(); 0111 const int dayOfWeek = d.dayOfWeek(); 0112 QDate currentDate = d.addDays(weekStart - dayOfWeek); 0113 0114 if (weekStart != 1 && dayOfWeek < weekStart) { 0115 currentDate = currentDate.addDays(-7); 0116 } 0117 0118 mSelectedDates.clear(); 0119 const int mask = KOGlobals::self()->getWorkWeekMask(); 0120 0121 for (int i = 0; i < 7; ++i) { 0122 if ((1 << ((i + weekStart + 6) % 7)) & (mask)) { 0123 mSelectedDates.append(currentDate.addDays(i)); 0124 } 0125 } 0126 0127 emitSelected(/* preferredMonth= */ d); 0128 } 0129 0130 void DateNavigator::selectToday() 0131 { 0132 const QDate d = QDate::currentDate(); 0133 0134 const int dateCount = mSelectedDates.count(); 0135 0136 if (dateCount == 7) { 0137 selectWeek(d, /* preferredMonth= */ d); 0138 } else if (dateCount == 5) { 0139 selectWorkWeek(d); 0140 } else { 0141 selectDates(d, dateCount); 0142 } 0143 } 0144 0145 void DateNavigator::selectPreviousYear() 0146 { 0147 QDate firstSelected = mSelectedDates.first(); 0148 const int weekDay = firstSelected.dayOfWeek(); 0149 firstSelected = firstSelected.addYears(-1); 0150 0151 selectWeekByDay(weekDay, firstSelected); 0152 } 0153 0154 void DateNavigator::selectPreviousMonth(const QDate ¤tMonth, const QDate &selectionLowerLimit, const QDate &selectionUpperLimit) 0155 { 0156 shiftMonth(currentMonth, selectionLowerLimit, selectionUpperLimit, -1); 0157 } 0158 0159 void DateNavigator::selectPreviousWeek() 0160 { 0161 QDate firstSelected = mSelectedDates.first(); 0162 const int weekDay = firstSelected.dayOfWeek(); 0163 firstSelected = firstSelected.addDays(-7); 0164 0165 selectWeekByDay(weekDay, firstSelected); 0166 } 0167 0168 void DateNavigator::selectNextWeek() 0169 { 0170 QDate firstSelected = mSelectedDates.first(); 0171 const int weekDay = firstSelected.dayOfWeek(); 0172 0173 firstSelected = firstSelected.addDays(7); 0174 0175 selectWeekByDay(weekDay, firstSelected); 0176 } 0177 0178 void DateNavigator::shiftMonth(const QDate ¤tMonth, const QDate &selectionLowerLimit, const QDate &selectionUpperLimit, int offset) 0179 { 0180 QDate firstSelected = mSelectedDates.first(); 0181 const int weekDay = firstSelected.dayOfWeek(); 0182 firstSelected = firstSelected.addMonths(offset); 0183 0184 /* Don't trust firstSelected to calculate the nextMonth. firstSelected 0185 can belong to a month other than currentMonth because KDateNavigator 0186 displays 7*6 days. firstSelected should only be used for selection 0187 purposes */ 0188 const QDate nextMonth = currentMonth.isValid() ? currentMonth.addMonths(offset) : firstSelected; 0189 0190 /* When firstSelected doesn't belong to currentMonth it can happen 0191 that the new selection won't be visible on our KDateNavigators 0192 so we must adjust it */ 0193 if (selectionLowerLimit.isValid() && firstSelected < selectionLowerLimit) { 0194 firstSelected = selectionLowerLimit; 0195 } else if (selectionUpperLimit.isValid() && firstSelected > selectionUpperLimit) { 0196 firstSelected = selectionUpperLimit.addDays(-6); 0197 } 0198 0199 selectWeekByDay(weekDay, firstSelected, nextMonth); 0200 } 0201 0202 void DateNavigator::selectNextMonth(const QDate ¤tMonth, const QDate &selectionLowerLimit, const QDate &selectionUpperLimit) 0203 { 0204 shiftMonth(currentMonth, selectionLowerLimit, selectionUpperLimit, 1); 0205 } 0206 0207 void DateNavigator::selectNextYear() 0208 { 0209 QDate firstSelected = mSelectedDates.first(); 0210 int weekDay = firstSelected.dayOfWeek(); 0211 firstSelected = firstSelected.addYears(1); 0212 0213 selectWeekByDay(weekDay, firstSelected); 0214 } 0215 0216 void DateNavigator::selectPrevious() 0217 { 0218 int offset = -7; 0219 if (datesCount() == 1) { 0220 offset = -1; 0221 } 0222 0223 selectDates(mSelectedDates.first().addDays(offset), datesCount()); 0224 } 0225 0226 void DateNavigator::selectNext() 0227 { 0228 int offset = 7; 0229 if (datesCount() == 1) { 0230 offset = 1; 0231 } 0232 0233 selectDates(mSelectedDates.first().addDays(offset), datesCount()); 0234 } 0235 0236 void DateNavigator::selectMonth(int month) 0237 { 0238 // always display starting at the first week of the specified month 0239 QDate firstSelected = QDate(mSelectedDates.first().year(), month, 1); 0240 0241 int day = firstSelected.day(); 0242 firstSelected.setDate(firstSelected.year(), month, 1); 0243 int days = firstSelected.daysInMonth(); 0244 // As day we use either the selected date, or if the month has less days 0245 // than that, we use the max day of that month 0246 if (day > days) { 0247 day = days; 0248 } 0249 QDate requestedMonth; 0250 firstSelected.setDate(firstSelected.year(), month, day); 0251 requestedMonth.setDate(firstSelected.year(), month, 1); 0252 0253 selectWeekByDay(1, firstSelected, requestedMonth); 0254 } 0255 0256 void DateNavigator::selectYear(int year) 0257 { 0258 QDate firstSelected = mSelectedDates.first(); 0259 const int deltaYear = year - firstSelected.year(); 0260 firstSelected = firstSelected.addYears(deltaYear); 0261 0262 const int weekDay = firstSelected.dayOfWeek(); 0263 selectWeekByDay(weekDay, firstSelected); 0264 } 0265 0266 void DateNavigator::emitSelected(const QDate &preferredMonth) 0267 { 0268 Q_EMIT datesSelected(mSelectedDates, preferredMonth); 0269 } 0270 0271 #include "moc_datenavigator.cpp"