File indexing completed on 2024-05-05 05:48:32
0001 /* 0002 CT Unit of Time Interval Implementation 0003 -------------------------------------------------------------------- 0004 SPDX-FileCopyrightText: 1999 Gary Meyer <gary@meyer.net> 0005 -------------------------------------------------------------------- 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "ctunit.h" 0010 0011 #include <KLocalizedString> 0012 0013 CTUnit::CTUnit(int _min, int _max, const QString &tokStr) 0014 { 0015 mMin = _min; 0016 mMax = _max; 0017 initialize(tokStr); 0018 } 0019 0020 CTUnit::CTUnit(const CTUnit &source) 0021 { 0022 mMin = source.mMin; 0023 mMax = source.mMax; 0024 0025 mInitialEnabled.clear(); 0026 mEnabled.clear(); 0027 mInitialEnabled.reserve(mMax + 1); 0028 for (int i = 0; i <= mMax; i++) { 0029 mInitialEnabled.append(false); 0030 mEnabled.append(source.mEnabled.at(i)); 0031 } 0032 0033 mInitialTokStr = QLatin1String(""); 0034 mDirty = true; 0035 } 0036 0037 CTUnit::~CTUnit() 0038 { 0039 } 0040 0041 CTUnit &CTUnit::operator=(const CTUnit &unit) 0042 { 0043 if (this == &unit) { 0044 return *this; 0045 } 0046 0047 mMin = unit.mMin; 0048 mMax = unit.mMax; 0049 0050 mEnabled.clear(); 0051 for (int i = 0; i <= mMax; i++) { 0052 mEnabled.append(unit.mEnabled[i]); 0053 } 0054 mDirty = true; 0055 0056 return *this; 0057 } 0058 0059 void CTUnit::initialize(const QString &tokStr) 0060 { 0061 mEnabled.clear(); 0062 for (int i = 0; i <= mMax; i++) { 0063 mEnabled.append(false); 0064 mInitialEnabled.append(false); 0065 } 0066 0067 for (int i = mMin; i <= mMax; i++) { 0068 mInitialEnabled[i] = mEnabled[i]; 0069 } 0070 0071 parse(tokStr); 0072 mInitialTokStr = tokStr; 0073 mDirty = false; 0074 } 0075 0076 void CTUnit::parse(const QString &tokenString) 0077 { 0078 QString tokStr = tokenString; 0079 0080 // subelement is that which is between commas 0081 QString subelement; 0082 int commapos, slashpos, dashpos; 0083 int beginat, endat, step; 0084 0085 // loop through each subelement 0086 tokStr += QLatin1Char(','); 0087 while ((commapos = tokStr.indexOf(QLatin1Char(','))) > 0) { 0088 subelement = tokStr.mid(0, commapos); 0089 0090 // find "/" to determine step 0091 slashpos = subelement.indexOf(QLatin1Char('/')); 0092 if (slashpos == -1) { 0093 step = 1; 0094 slashpos = subelement.length(); 0095 } else { 0096 step = fieldToValue(subelement.mid(slashpos + 1, subelement.length() - slashpos - 1)); 0097 if (step < 1) { 0098 step = 1; 0099 } 0100 } 0101 0102 // find "=" to determine range 0103 dashpos = subelement.indexOf(QLatin1Char('-')); 0104 if (dashpos == -1) { 0105 // deal with "*" 0106 if (subelement.mid(0, slashpos) == QLatin1Char('*')) { 0107 beginat = mMin; 0108 endat = mMax; 0109 } else { 0110 beginat = fieldToValue(subelement.mid(0, slashpos)); 0111 endat = beginat; 0112 } 0113 } else { 0114 beginat = fieldToValue(subelement.mid(0, dashpos)); 0115 endat = fieldToValue(subelement.mid(dashpos + 1, slashpos - dashpos - 1)); 0116 } 0117 0118 // ignore out of range 0119 if (beginat < 0) { 0120 beginat = 0; 0121 } 0122 if (endat > mMax) { 0123 endat = mMax; 0124 } 0125 0126 // setup enabled 0127 for (int i = beginat; i <= endat; i += step) { 0128 mInitialEnabled[i] = mEnabled[i] = true; 0129 } 0130 0131 tokStr = tokStr.mid(commapos + 1, tokStr.length() - commapos - 1); 0132 } 0133 } 0134 0135 QString CTUnit::exportUnit() const 0136 { 0137 if (!mDirty) { 0138 return mInitialTokStr; 0139 } 0140 0141 if (isAllEnabled()) { 0142 return QStringLiteral("*"); 0143 } 0144 0145 int total = enabledCount(); 0146 int count = 0; 0147 QString tokenizeUnit; 0148 0149 for (int num = mMin; num <= mMax; num++) { 0150 if (mEnabled[num]) { 0151 tokenizeUnit += QString::number(num); 0152 count++; 0153 0154 if (count < total) { 0155 tokenizeUnit += QLatin1Char(','); 0156 } 0157 } 0158 } 0159 0160 return tokenizeUnit; 0161 } 0162 0163 QString CTUnit::genericDescribe(const QList<QString> &label) const 0164 { 0165 int total(enabledCount()); 0166 int count(0); 0167 QString tmpStr; 0168 for (int i = mMin; i <= mMax; i++) { 0169 if (mEnabled[i]) { 0170 tmpStr += label.at(i); 0171 count++; 0172 switch (total - count) { 0173 case 0: 0174 break; 0175 case 1: 0176 if (total > 2) { 0177 tmpStr += i18n(","); 0178 } 0179 tmpStr += i18n(" and "); 0180 break; 0181 default: 0182 tmpStr += i18n(", "); 0183 break; 0184 } 0185 } 0186 } 0187 return tmpStr; 0188 } 0189 0190 int CTUnit::minimum() const 0191 { 0192 return mMin; 0193 } 0194 0195 int CTUnit::maximum() const 0196 { 0197 return mMax; 0198 } 0199 0200 bool CTUnit::isEnabled(int pos) const 0201 { 0202 return mEnabled.at(pos); 0203 } 0204 0205 bool CTUnit::isAllEnabled() const 0206 { 0207 for (int i = mMin; i <= mMax; i++) { 0208 if (!mEnabled.at(i)) { 0209 return false; 0210 } 0211 } 0212 0213 return true; 0214 } 0215 0216 void CTUnit::setEnabled(int pos, bool value) 0217 { 0218 mEnabled[pos] = value; 0219 mDirty = true; 0220 return; 0221 } 0222 0223 bool CTUnit::isDirty() const 0224 { 0225 return mDirty; 0226 } 0227 0228 int CTUnit::enabledCount() const 0229 { 0230 int total(0); 0231 for (int i = mMin; i <= mMax; i++) { 0232 total += (mEnabled[i] == true); 0233 } 0234 return total; 0235 } 0236 0237 void CTUnit::apply() 0238 { 0239 mInitialTokStr = exportUnit(); 0240 for (int i = mMin; i <= mMax; i++) { 0241 mInitialEnabled[i] = mEnabled.at(i); 0242 } 0243 mDirty = false; 0244 } 0245 0246 void CTUnit::cancel() 0247 { 0248 for (int i = mMin; i <= mMax; i++) { 0249 mEnabled[i] = mInitialEnabled.at(i); 0250 } 0251 mDirty = false; 0252 } 0253 0254 int CTUnit::fieldToValue(const QString &entry) const 0255 { 0256 QString lower = entry.toLower(); 0257 0258 // check for days 0259 QList<QString> days; 0260 days << QStringLiteral("sun") << QStringLiteral("mon") << QStringLiteral("tue") << QStringLiteral("wed") << QStringLiteral("thu") << QStringLiteral("fri") 0261 << QStringLiteral("sat"); 0262 0263 int day = days.indexOf(lower); 0264 if (day != -1) { 0265 return day; 0266 } 0267 0268 // check for months 0269 QList<QString> months; 0270 months << QLatin1String("") << QStringLiteral("jan") << QStringLiteral("feb") << QStringLiteral("mar") << QStringLiteral("apr") << QStringLiteral("may") 0271 << QStringLiteral("jun") << QStringLiteral("jul") << QStringLiteral("aug") << QStringLiteral("sep") << QStringLiteral("oct") << QStringLiteral("nov") 0272 << QStringLiteral("dec"); 0273 0274 int month = months.indexOf(lower); 0275 if (month != -1) { 0276 return month; 0277 } 0278 0279 // If the string does not match a day ora month, then it's a simple number (minute, hour or day of month) 0280 return entry.toInt(); 0281 } 0282 0283 /** 0284 * Find a period in enabled values 0285 * If no period has been found, return 0 0286 */ 0287 int CTUnit::findPeriod(const QList<int> &periods) const 0288 { 0289 for (int period : periods) { 0290 bool validPeriod = true; 0291 0292 for (int i = minimum(); i <= maximum(); i++) { 0293 bool periodTesting; 0294 if ((double)i / (double)period == i / period) { 0295 periodTesting = true; 0296 } else { 0297 periodTesting = false; 0298 } 0299 0300 if (isEnabled(i) != periodTesting) { 0301 validPeriod = false; 0302 break; 0303 } 0304 } 0305 0306 if (validPeriod) { 0307 return period; 0308 } 0309 } 0310 0311 return 0; 0312 }