CalendarSupport

freeperiodmodel.cpp
1/*
2 SPDX-FileCopyrightText: 2010 Casey Link <unnamedrambler@gmail.com>
3 SPDX-FileCopyrightText: 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "freeperiodmodel.h"
9
10#include <KFormat>
11#include <KLocalizedString>
12
13#include <QDateTime>
14#include <QLocale>
15#include <QTimeZone>
16
17using namespace CalendarSupport;
18
19FreePeriodModel::FreePeriodModel(QObject *parent)
20 : QAbstractTableModel(parent)
21{
22}
23
24FreePeriodModel::~FreePeriodModel() = default;
25
26QVariant FreePeriodModel::data(const QModelIndex &index, int role) const
27{
28 if (!index.isValid() || !hasIndex(index.row(), index.column())) {
29 return {};
30 }
31
32 if (index.column() == 0) { // day
33 switch (role) {
34 case Qt::DisplayRole:
35 return day(index.row());
36 case Qt::ToolTipRole:
37 return tooltipify(index.row());
38 case FreePeriodModel::PeriodRole:
39 return QVariant::fromValue(mPeriodList.at(index.row()));
41 return static_cast<int>(Qt::AlignRight | Qt::AlignVCenter);
42 default:
43 return {};
44 }
45 } else { // everything else
46 switch (role) {
47 case Qt::DisplayRole:
48 return date(index.row());
49 case Qt::ToolTipRole:
50 return tooltipify(index.row());
51 case FreePeriodModel::PeriodRole:
52 return QVariant::fromValue(mPeriodList.at(index.row()));
54 return static_cast<int>(Qt::AlignLeft | Qt::AlignVCenter);
55 default:
56 return {};
57 }
58 }
59}
60
61int FreePeriodModel::rowCount(const QModelIndex &parent) const
62{
63 if (!parent.isValid()) {
64 return mPeriodList.size();
65 }
66 return 0;
67}
68
69int FreePeriodModel::columnCount(const QModelIndex &parent) const
70{
71 Q_UNUSED(parent)
72 return 2;
73}
74
75QVariant FreePeriodModel::headerData(int section, Qt::Orientation orientation, int role) const
76{
77 return QAbstractItemModel::headerData(section, orientation, role);
78}
79
80void FreePeriodModel::slotNewFreePeriods(const KCalendarCore::Period::List &freePeriods)
81{
83 mPeriodList.clear();
84 mPeriodList = splitPeriodsByDay(freePeriods);
85 std::sort(mPeriodList.begin(), mPeriodList.end());
87}
88
89KCalendarCore::Period::List FreePeriodModel::splitPeriodsByDay(const KCalendarCore::Period::List &freePeriods)
90{
92 for (const KCalendarCore::Period &period : freePeriods) {
93 if (period.start().date() == period.end().date()) {
94 splitList << period; // period occurs on the same day
95 continue;
96 }
97
98 const int validPeriodSecs = 300; // 5 minutes
99 KCalendarCore::Period tmpPeriod = period;
100 while (tmpPeriod.start().date() != tmpPeriod.end().date()) {
101 const QDateTime midnight(tmpPeriod.start().date(), QTime(23, 59, 59, 999), tmpPeriod.start().timeZone());
102 KCalendarCore::Period firstPeriod(tmpPeriod.start(), midnight);
103 KCalendarCore::Period secondPeriod(midnight.addMSecs(1), tmpPeriod.end());
104 if (firstPeriod.duration().asSeconds() >= validPeriodSecs) {
105 splitList << firstPeriod;
106 }
107 tmpPeriod = secondPeriod;
108 }
109 if (tmpPeriod.duration().asSeconds() >= validPeriodSecs) {
110 splitList << tmpPeriod;
111 }
112 }
113
114 // Perform some jiggery pokery to remove duplicates
115 std::sort(splitList.begin(), splitList.end());
116 splitList.erase(std::unique(splitList.begin(), splitList.end()), splitList.end());
117 return splitList;
118}
119
120QString FreePeriodModel::day(int index) const
121{
122 KCalendarCore::Period period = mPeriodList.at(index);
123 const QDate startDate = period.start().date();
124 return ki18nc("@label Day of the week name, example: Monday,", "%1,")
125 .subs(QLocale::system().dayName(startDate.dayOfWeek(), QLocale::LongFormat))
126 .toString();
127}
128
129QString FreePeriodModel::date(int index) const
130{
131 KCalendarCore::Period period = mPeriodList.at(index);
132
133 const QDate startDate = period.start().date();
134 const QString startTime = QLocale::system().toString(period.start().time(), QLocale::ShortFormat);
135 const QString endTime = QLocale::system().toString(period.end().time(), QLocale::ShortFormat);
136 const QString longMonthName = QLocale::system().monthName(startDate.month());
137 return ki18nc(
138 "@label A time period duration. It is preceded/followed (based on the "
139 "orientation) by the name of the week, see the message above. "
140 "example: 12 June, 8:00am to 9:30am",
141 "%1 %2, %3 to %4")
142 .subs(startDate.day())
143 .subs(longMonthName)
144 .subs(startTime)
145 .subs(endTime)
146 .toString();
147}
148
149QString FreePeriodModel::stringify(int index) const
150{
151 KCalendarCore::Period period = mPeriodList.at(index);
152
153 const QDate startDate = period.start().date();
154 const QString startTime = QLocale().toString(period.start().time(), QLocale::ShortFormat);
155 const QString endTime = QLocale().toString(period.end().time(), QLocale::ShortFormat);
156 const QString longMonthName = QLocale::system().monthName(startDate.month(), QLocale::LongFormat);
157 const QString dayofWeek = QLocale::system().dayName(startDate.dayOfWeek(), QLocale::LongFormat);
158
159 return ki18nc(
160 "@label A time period duration. KLocale is used to format the components. "
161 "example: Monday, 12 June, 8:00am to 9:30am",
162 "%1, %2 %3, %4 to %5")
163 .subs(dayofWeek)
164 .subs(startDate.day())
165 .subs(longMonthName)
166 .subs(startTime)
167 .subs(endTime)
168 .toString();
169}
170
171QString FreePeriodModel::tooltipify(int index) const
172{
173 KCalendarCore::Period period = mPeriodList.at(index);
174 unsigned long duration = period.duration().asSeconds() * 1000; // we want milliseconds
175 QString toolTip = QStringLiteral("<qt>");
176 toolTip += QLatin1StringView("<b>") + i18nc("@info:tooltip", "Free Period") + QLatin1StringView("</b>");
177 toolTip += QLatin1StringView("<hr>");
178 toolTip += QLatin1StringView("<i>") + i18nc("@info:tooltip period start time", "Start:") + QLatin1StringView("</i>&nbsp;");
179 toolTip += QLocale().toString(period.start().toLocalTime(), QLocale::ShortFormat);
180 toolTip += QLatin1StringView("<br>");
181 toolTip += QLatin1StringView("<i>") + i18nc("@info:tooltip period end time", "End:") + QLatin1StringView("</i>&nbsp;");
182 toolTip += QLocale().toString(period.end().toLocalTime(), QLocale::ShortFormat);
183 toolTip += QLatin1StringView("<br>");
184 toolTip += QLatin1StringView("<i>") + i18nc("@info:tooltip period duration", "Duration:") + QLatin1StringView("</i>&nbsp;");
185 toolTip += KFormat().formatSpelloutDuration(duration);
186 toolTip += QLatin1StringView("</qt>");
187 return toolTip;
188}
189
190#include "moc_freeperiodmodel.cpp"
QDateTime end() const
QList< Period > List
Duration duration() const
QDateTime start() const
QString toString() const
KLocalizedString subs(const KLocalizedString &a, int fieldWidth=0, QChar fillChar=QLatin1Char(' ')) const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
KLocalizedString KI18N_EXPORT ki18nc(const char *context, const char *text)
bool hasIndex(int row, int column, const QModelIndex &parent) const const
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const const
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const=0
virtual QModelIndex parent(const QModelIndex &index) const const=0
int day() const const
int dayOfWeek() const const
int month() const const
QDate date() const const
QTime time() const const
QTimeZone timeZone() const const
QDateTime toLocalTime() const const
const_reference at(qsizetype i) const const
iterator begin()
iterator end()
iterator erase(const_iterator begin, const_iterator end)
QString dayName(int day, FormatType type) const const
QString monthName(int month, FormatType type) const const
QLocale system()
QString toString(QDate date, FormatType format) const const
AlignRight
DisplayRole
Orientation
QVariant fromValue(T &&value)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:57:25 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.