• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.10 API Reference
  • KDE Home
  • Contact Us
 

KHolidays Library

  • kholidays
  • parsers
  • plan2
holidayparserdriverplan.cpp
1/*
2 Original version from plan by Thomas Driemeyer <thomas@bitrot.de>
3
4 Adapted for use in KOrganizer by
5 Preston Brown <pbrown@kde.org> and
6 Reinhold Kainhofer <reinhold@kainhofer.com>
7
8 Portions contributed by
9 Peter Littlefield <plittle@sofkin.ca>
10 Armin Liebl <liebla@informatik.tu-muenchen.de>
11 Efthimios Mavrogeorgiadis <emav@enl.auth.gr>
12 Erwin Hugo Achermann <acherman@inf.ethz.ch>
13
14 Major rewrite using Bison C++ skeleton:
15 Copyright 2010 John Layt <john@layt.net>
16
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Library General Public
19 License as published by the Free Software Foundation; either
20 version 2 of the License, or (at your option) any later version.
21
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU Library General Public License for more details.
26
27 You should have received a copy of the GNU Library General Public License
28 along with this library; see the file COPYING.LIB. If not, write to the
29 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
30 Boston, MA 02110-1301, USA.
31*/
32
33#include "holidayparserdriverplan_p.h"
34#include "holidayscannerplan_p.h"
35#include "holidayparserplan.hpp"
36
37#include <sstream>
38
39#include <QFileInfo>
40
41#include <KCalendarSystem>
42#include <kdebug.h>
43
44#include "holiday_p.h"
45
46#define LAST 99999
47#define ANY -99999
48#define BEFORE -1
49#define AFTER 1
50
51using namespace KHolidays;
52
53HolidayParserDriverPlan::HolidayParserDriverPlan( const QString &planFilePath )
54 :HolidayParserDriver( planFilePath ),
55 m_traceParsing( false ),
56 m_traceScanning( false ),
57 m_parseMetadataOnly( false )
58{
59 QFile holidayFile( filePath() );
60 if ( holidayFile.open( QIODevice::ReadOnly ) ) {
61 m_scanData = holidayFile.readAll();
62 holidayFile.close();
63 }
64 m_scanner = new HolidayScannerPlan();
65 m_scanner->set_debug( m_traceScanning );
66 m_parser = new HolidayParserPlan( *this );
67 m_parser->set_debug_level( m_traceParsing );
68 m_fileToParse = new std::string( filePath().toLocal8Bit().data() );
69 parseMetadata();
70}
71
72HolidayParserDriverPlan::~HolidayParserDriverPlan()
73{
74 delete m_parser;
75 delete m_scanner;
76 delete m_fileToParse;
77}
78
79//TODO Figure why it doesn't compile
80void HolidayParserDriverPlan::error( const KHolidays::location &errorLocation, const QString &errorMessage )
81{
82 Q_UNUSED( errorLocation );
83 //std::cerr << errorLocation << " : " << errorMessage; //Doesn't work???
84 //kDebug() << errorLocation << " : " << errorMessage; //Doesn't work???
85 kDebug() << errorMessage;
86}
87
88void HolidayParserDriverPlan::error( const QString &errorMessage )
89{
90 kDebug() << errorMessage;
91}
92
93
94void HolidayParserDriverPlan::parse()
95{
96 // Parse the file using every calendar system in the file
97 foreach ( const QString &calendar, m_fileCalendarTypes ) {
98
99 // Cater for events defined in other Calendar Systems where request year could cover 2 or 3 event years
100 // Perhaps also parse year before and year after to allow events to span years or shift to other year?
101 setParseCalendar( calendar );
102 setParseStartEnd();
103
104 // Generate all events for this calendar in the required year(s)
105 for ( m_parseYear = m_parseStartYear; m_parseYear <= m_parseEndYear; ++m_parseYear ) {
106
107 m_parseCalendar->setDate( m_parseYearStart, m_parseYear, 1, 1 );
108 m_parseYearEaster = easter( m_parseYear );
109 m_parseYearPascha = pascha( m_parseYear );
110
111 std::istringstream iss2( std::string( m_scanData.data() ) );
112 m_scanner->yyrestart( &iss2 );
113
114 m_parser->parse();
115 }
116
117 }
118}
119
120void HolidayParserDriverPlan::parseMetadata()
121{
122 m_parseMetadataOnly = true;
123 m_fileCountryCode.clear();
124 m_fileLanguageCode.clear();
125 m_fileName.clear();
126 m_fileDescription.clear();
127 m_fileCalendarTypes.clear();
128 m_fileCalendarTypes.append( QLatin1String("gregorian") );
129
130 // Default to files internal metadata
131 setParseCalendar( QLatin1String("gregorian") );
132 m_parseYear = QDate::currentDate().year();
133 std::istringstream iss2( std::string( m_scanData.data() ) );
134 m_scanner->yyrestart( &iss2 );
135 m_parser->parse();
136 m_resultList.clear();
137
138 // If not populated, then use filename metadata, this may change later
139 // metadata is encoded in filename in form holiday_<region>_<type>_<language>_<name>
140 // with region, type and language sub groups separated by -, and with name optional
141 QFileInfo file( m_filePath );
142 if ( file.exists() ) {
143 QStringList metadata = file.fileName().split( QLatin1Char('_') );
144 if ( metadata[0] == QLatin1String("holiday") && metadata.count() > 2 ) {
145 if ( m_fileCountryCode.isEmpty() ) {
146 setFileCountryCode( metadata[1].toUpper() );
147 }
148 if ( m_fileLanguageCode.isEmpty() ) {
149 QStringList language = metadata[2].split( QLatin1Char('-') );
150 m_fileLanguageCode = language[0];
151 if ( language.count() > 1 ) {
152 setFileLanguageCode( language[0].append( QLatin1Char('_') ).append( language[1].toUpper() ) );
153 } else {
154 setFileLanguageCode( language[0] );
155 }
156 }
157 if ( m_fileLanguageCode.isEmpty() && metadata.count() > 3 ) {
158 m_fileName = metadata[3];
159 }
160 }
161 }
162
163 m_parseMetadataOnly = false;
164}
165
166QString HolidayParserDriverPlan::filePath()
167{
168 return m_filePath;
169}
170
171std::string *HolidayParserDriverPlan::fileToParse() const
172{
173 return m_fileToParse;
174}
175
176/*****************************************
177 Calendar and Date convenience routines
178******************************************/
179
180// Adjust month numbering for Hebrew civil calendar leap month
181int HolidayParserDriverPlan::adjustedMonthNumber( int month )
182{
183 if ( m_eventCalendarType != QLatin1String("hebrew") || // Only adjust Hebrew months
184 m_parseCalendar->calendarType() != QLatin1String("hebrew") ||
185 !m_parseCalendar->isLeapYear( m_parseYear ) || // Only adjust in leap year
186 month < 6 ) { // Only adjust from Adar onwards
187 return month;
188 }
189
190 if ( month == 13 ) { // Adar I
191 return 6;
192 }
193
194 if ( month == 14 ) { // Adar II
195 return 7;
196 }
197
198 return month + 1; // Inserting Adar I moves other months up by 1
199}
200
201bool HolidayParserDriverPlan::isLeapYear( int year )
202{
203 return m_parseCalendar->isLeapYear( year );
204}
205
206int HolidayParserDriverPlan::parseYear()
207{
208 return m_parseYear;
209}
210
211int HolidayParserDriverPlan::monthsInYear( int year )
212{
213 QDate tempDate;
214 m_parseCalendar->setDate( tempDate, year, 1, 1 );
215 return m_parseCalendar->monthsInYear( tempDate );
216}
217
218int HolidayParserDriverPlan::daysInMonth( int year, int month )
219{
220 QDate tempDate;
221 m_parseCalendar->setDate( tempDate, year, month, 1 );
222 return m_parseCalendar->daysInMonth( tempDate );
223}
224
225int HolidayParserDriverPlan::julianDay( int year, int month, int day )
226{
227 QDate tempDate;
228 m_parseCalendar->setDate( tempDate, year, month, day );
229 return tempDate.toJulianDay();
230}
231
232void HolidayParserDriverPlan::julianDayToDate( int jd, int *year, int *month, int *day )
233{
234 QDate tempDate = QDate::fromJulianDay( jd );
235
236 if ( year ) {
237 *year = m_parseCalendar->year( tempDate );
238 }
239 if ( month ) {
240 *month = m_parseCalendar->month( tempDate );
241 }
242 if ( day ) {
243 *day = m_parseCalendar->day( tempDate );
244 }
245}
246
247QDate HolidayParserDriverPlan::easter( int year )
248{
249 if ( m_parseCalendar->calendarType() != QLatin1String("gregorian") ) {
250 return QDate();
251 }
252
253 // Algorithm taken from Tondering
254 // http://www.tondering.dk/claus/cal/node3.html#SECTION003137000000000000000
255 int g = year % 19;
256 int c = year / 100;
257 int h = ( c - ( c / 4 ) - ( ( ( 8 * c ) + 13 ) / 25 ) + ( 19 * g ) + 15 ) % 30;
258 int i = h - ( ( h / 28 ) * ( 1 - ( ( 29 / ( h + 1 ) ) * ( ( 21 - g ) / 11 ) ) ) );
259 int j = ( year + ( year / 4 ) + i + 2 - c + ( c / 4 ) ) % 7;
260 int l = i - j;
261 int month = 3 + ( ( l + 40 ) / 44 );
262 int day = l + 28 - ( 31 * ( month / 4 ) );
263
264 return QDate::fromJulianDay( julianDay( year, month, day ) );
265}
266
267
268QDate HolidayParserDriverPlan::pascha( int year )
269{
270 if ( m_parseCalendar->calendarType() == QLatin1String("gregorian") ||
271 m_parseCalendar->calendarType() == QLatin1String("julian") ) {
272 // Algorithm taken from Tondering
273 // http://www.tondering.dk/claus/cal/node3.html#SECTION003137000000000000000
274 // Gives Orthodox Easter in the Julian Calendar, need to convert afterwards to Gregorian if needed
275 int g = year % 19;
276 int i = ( ( 19 * g ) + 15 ) % 30;
277 int j = ( year + ( year / 4 ) + i ) % 7;
278 int l = i - j;
279 int month = 3 + ( ( l + 40 ) / 44 );
280 int day = l + 28 - ( 31 * ( month / 4 ) );
281
282 if ( m_parseCalendar->calendarType() == QLatin1String("julian") ) {
283 return QDate::fromJulianDay( julianDay( year, month, day ) );
284 }
285
286 if ( m_parseCalendar->calendarType() == QLatin1String("gregorian") ) {
287 setParseCalendar( QLatin1String("julian") );
288 int paschaJd = julianDay( year, month, day );
289 setParseCalendar( QLatin1String("gregorian") );
290 return QDate::fromJulianDay( paschaJd );
291 }
292 }
293
294 return QDate();
295}
296
297
298/*************************
299 * Calculate jd routines *
300 *************************/
301
302// Return the jd of an existing event, assumes unique names and correct order in file
303int HolidayParserDriverPlan::julianDayFromEventName( const QString &eventName )
304{
305 foreach ( const KHolidays::Holiday &thisHoliday, m_resultList ) {
306 if ( thisHoliday.text() == eventName ) {
307 return thisHoliday.date().toJulianDay();
308 }
309 }
310 return -1;
311}
312
313// Return jd of Easter if Gregorian
314int HolidayParserDriverPlan::julianDayFromEaster( void )
315{
316 if ( m_eventCalendarType == QLatin1String("gregorian") ) {
317 return m_parseYearEaster.toJulianDay();
318 } else {
319 error( QLatin1String("Can only use Easter in Gregorian event rule") );
320 return -1;
321 }
322}
323
324// Return jd of Orthodox Easter if Gregorian or Julian
325int HolidayParserDriverPlan::julianDayFromPascha( void )
326{
327 if ( m_eventCalendarType == QLatin1String("gregorian") || m_eventCalendarType == QLatin1String("julian") ) {
328 return m_parseYearPascha.toJulianDay();
329 } else {
330 error( QLatin1String("Can only use Easter in Gregorian or Julian event rule") );
331 return -1;
332 }
333}
334
335// Return jd of weekday from a month/day in parse year
336int HolidayParserDriverPlan::julianDayFromMonthDay( int month, int day ) {
337 return julianDay( m_parseYear, month, day );
338}
339
340// Return jd of weekday relative to a Julian Day number
341int HolidayParserDriverPlan::julianDayFromRelativeWeekday( int occurrence, int weekday, int jd )
342{
343 if ( occurrence == ANY ) { /* Should never get this, convert to AFTER instead */
344 occurrence = AFTER;
345 }
346
347 int thisWeekday = m_parseCalendar->dayOfWeek( QDate::fromJulianDay( jd ) );
348
349 /* AFTER actually means on or after */
350 /* BEFORE actually means on or before */
351 if ( occurrence > 0 ) {
352 occurrence = occurrence - 1;
353 } else if ( occurrence < 0 && weekday == thisWeekday ) {
354 occurrence = occurrence + 1;
355 }
356
357 if ( weekday < thisWeekday ) {
358 occurrence = occurrence + 1;
359 }
360
361 return jd + weekday - thisWeekday + ( occurrence * 7 );
362}
363
364// Return jd of weekday occurence in a given month and day in the parse year
365int HolidayParserDriverPlan::julianDayFromWeekdayInMonth( int occurrence, int weekday, int month )
366{
367 if ( occurrence == LAST ) { // Is weekday on or before last day of month
368 return julianDayFromRelativeWeekday( BEFORE, weekday, julianDay( m_parseYear, month, daysInMonth( m_parseYear, month ) ) );
369 } else { // Is nth weekday on or after first day of month
370 return julianDayFromRelativeWeekday( occurrence, weekday, julianDay( m_parseYear, month, 1 ) );
371 }
372}
373
374
375/****************************************************
376 * Set parsed event variables convenience functions *
377 ****************************************************/
378
379void HolidayParserDriverPlan::setFileCountryCode( const QString &countryCode )
380{
381 m_fileCountryCode = countryCode;
382}
383
384void HolidayParserDriverPlan::setFileLanguageCode( const QString &languageCode )
385{
386 m_fileLanguageCode = languageCode;
387}
388
389void HolidayParserDriverPlan::setFileName( const QString &name )
390{
391 m_fileName = name;
392}
393
394void HolidayParserDriverPlan::setFileDescription( const QString &description )
395{
396 m_fileDescription = description;
397}
398
399void HolidayParserDriverPlan::setEventName( const QString &eventName )
400{
401 // Assume if setting an event name then is start of new event line, so clear categories
402 m_eventCategories.clear();
403 m_eventName = eventName;
404}
405
406void HolidayParserDriverPlan::setEventCategory( const QString &category )
407{
408 m_eventCategories.append( category );
409}
410
411void HolidayParserDriverPlan::setEventCalendarType( const QString &calendarType )
412{
413 m_eventCalendarType = calendarType;
414 if ( m_parseMetadataOnly && !m_fileCalendarTypes.contains( calendarType ) ) {
415 m_fileCalendarTypes.append( calendarType );
416 }
417}
418
419void HolidayParserDriverPlan::setEventDate( int eventYear, int eventMonth, int eventDay )
420{
421 m_eventYear = eventYear;
422 m_eventMonth = eventMonth;
423 m_eventDay = eventDay;
424}
425
426void HolidayParserDriverPlan::setEventDate( int jd )
427{
428 julianDayToDate( jd, &m_eventYear, &m_eventMonth, &m_eventDay );
429}
430
431/********************************************
432 * Set event date from event rules routines *
433 ********************************************/
434
435/*
436 * Set event by weekday (Monday..Sunday). The rule expression is
437 * "every <occurrence> <weekday> of <month> plus <offset> days length <duration> days".
438 * Occurrence and month can be ANY or LAST, offset and duration are optional.
439 */
440
441void HolidayParserDriverPlan::setFromWeekdayInMonth( int occurrence, int weekday, int month, int offset, int duration )
442{
443 // Don't set if only parsing metadata or calendar for event rule is not the current parse calendar
444 if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
445 return;
446 }
447
448 int startMonth, endMonth;
449 if ( month == LAST ) {
450 startMonth = monthsInYear( m_parseYear );
451 endMonth = startMonth;
452 } else if ( month == ANY ) {
453 startMonth = 1;
454 endMonth = monthsInYear( m_parseYear );
455 } else {
456 startMonth = month;
457 endMonth = month;
458 }
459
460 // Generate all events in the required event month(s)
461 for ( int thisMonth = startMonth; thisMonth <= endMonth; ++thisMonth ) {
462
463 if ( m_parseCalendar->isValid( m_parseYear, thisMonth, 1 ) ) {
464 int startOccurrence, endOccurrence;
465 if ( occurrence == ANY ) { // Generate 1st through 5th weekdays, assumes no month with > 35 days
466 startOccurrence = 1;
467 endOccurrence = 5;
468 } else { // Generate just nth or LAST weekday
469 startOccurrence = occurrence;
470 endOccurrence = occurrence;
471 }
472
473 int jdMonthStart = julianDay( m_parseYear, thisMonth, 1 );
474 int jdMonthEnd = julianDay( m_parseYear, thisMonth, daysInMonth( m_parseYear, thisMonth ) );
475
476 // Generate each required occurrence of weekday in month, check occurrence actually falls in month
477 for ( int thisOccurrence = startOccurrence; thisOccurrence <= endOccurrence; ++thisOccurrence ) {
478 int thisJd = julianDayFromWeekdayInMonth( thisOccurrence, weekday, thisMonth );
479 if ( thisJd >= jdMonthStart && thisJd <= jdMonthEnd ) {
480 setEvent( thisJd + offset, 0, duration );
481 }
482 }
483 }
484
485 }
486}
487
488/*
489 * Set event by weekday (Monday..Sunday) relative to a date. The expression is
490 * "<weekday> <occurrence> <date> plus <offset> days length <duration> days".
491 * Occurrence, month and day can be ANY or LAST, year can be ANY, offset and duration are optional.
492 */
493
494void HolidayParserDriverPlan::setFromRelativeWeekday( int occurrence, int weekday, int offset, int duration )
495{
496 // Don't set if only parsing metadata or calendar for event rule is not the current parse calendar
497 if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
498 return;
499 }
500
501 int thisYear;
502 if ( m_eventYear == ANY ) { // Generate the parse year
503 thisYear = m_parseYear;
504 } else { // Generate a specific event year
505 thisYear = m_eventYear;
506 }
507
508 int startMonth, endMonth;
509 if ( m_eventMonth == LAST ) { // Generate just the last month
510 startMonth = monthsInYear( thisYear );
511 endMonth = startMonth;
512 } else if ( m_eventMonth == ANY ) { // Generate every month
513 startMonth = 1;
514 endMonth = monthsInYear( thisYear );
515 } else { // Generate just the specific event month
516 startMonth = m_eventMonth;
517 endMonth = m_eventMonth;
518 }
519
520 // Generate all events in the required month(s)
521 int thisMonth;
522 for ( thisMonth = startMonth; thisMonth <= endMonth; ++thisMonth ) {
523
524 int startDay, endDay;
525 if ( m_eventDay == LAST ) { // Generate just the last day in the month
526 startDay = daysInMonth( thisYear, thisMonth );
527 endDay = startDay;
528 } else if ( m_eventDay == ANY ) { // Generate every day in the month
529 startDay = 1;
530 endDay = daysInMonth( thisYear, thisMonth );
531 } else { // Generate just the specific event day
532 startDay = m_eventDay;
533 endDay = m_eventDay;
534 }
535
536 // Generate all events on the required day(s)
537 for ( int thisDay = startDay; thisDay <= endDay; ++thisDay ) {
538 if ( m_parseCalendar->isValid( thisYear, thisMonth, thisDay ) ) {
539 int relativeJd = julianDayFromRelativeWeekday( occurrence, weekday, julianDay( thisYear, thisMonth, thisDay ) );
540 setEvent( relativeJd + offset, 0, duration );
541 }
542 }
543
544 }
545}
546
547// TODO Figure out how this works :-)
548int HolidayParserDriverPlan::conditionalOffset( int year, int month, int day, int condition )
549{
555 int offset = 0;
556
557 QDate tempDate;
558 m_parseCalendar->setDate( tempDate, year, month, day );
559 int weekday = m_parseCalendar->dayOfWeek( tempDate );
560
561 if ( condition & ( 1 << weekday ) ) {
562 /* condition matches -> higher 8 bits contain the possible days to shift to */
563 int to = ( condition >> 8 );
564 while ( !( to & ( 1 << ( ( weekday + offset ) % 7 ) ) ) && ( offset < 8 ) ) {
565 ++offset;
566 }
567 }
568
569 if ( offset >= 8 ) {
570 offset = 0;
571 }
572
573 return offset;
574}
575
576/*
577 * Set event by date. The expression is
578 * "<date> plus <offset> days shift <condition> length <duration> days".
579 * Occurrence, month and day can be ANY or LAST, year can be ANY, offset and duration are optional.
580 */
581
582void HolidayParserDriverPlan::setFromDate( int offset, int condition, int duration )
583{
584 // Don't set if only parsing metadata or calendar for event rule is not the current parse calendar
585 if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
586 return;
587 }
588
589 int thisYear;
590 if ( m_eventYear == ANY ) { // Generate the parse year
591 thisYear = m_parseYear;
592 } else { // Generate a specific event year
593 thisYear = m_eventYear;
594 }
595
596 int startMonth, endMonth;
597 if ( m_eventMonth == LAST ) { // Generate just the last month
598 startMonth = monthsInYear( thisYear );
599 endMonth = startMonth;
600 } else if ( m_eventMonth == ANY ) { // Generate every month
601 startMonth = 1;
602 endMonth = monthsInYear( thisYear );
603 } else { // Generate just the specific event month
604 startMonth = m_eventMonth;
605 endMonth = m_eventMonth;
606 }
607
608 // Generate all events in the required month(s)
609 for ( int thisMonth = startMonth; thisMonth <= endMonth; ++thisMonth ) {
610
611 int startDay, endDay;
612 if ( m_eventDay == LAST ) { // Generate just the last day in the month
613 startDay = daysInMonth( thisYear, thisMonth );
614 endDay = startDay;
615 } else if ( m_eventDay == ANY ) { // Generate every day in the month
616 startDay = 1;
617 endDay = daysInMonth( thisYear, thisMonth );
618 } else { // Generate just the specific event day
619 startDay = m_eventDay;
620 endDay = m_eventDay;
621 }
622
623 // Generate all events on the required day(s)
624 for ( int thisDay = startDay; thisDay <= endDay; ++thisDay ) {
625
626 if ( m_parseCalendar->isValid( thisYear, thisMonth, thisDay ) ) {
627 setEvent( julianDay( thisYear, thisMonth, thisDay ) + offset,
628 conditionalOffset( thisYear, thisMonth, thisDay, condition ), duration );
629 }
630
631 }
632
633 }
634}
635
636/*
637 * Set event relative to Easter. The expression is
638 * "EASTER plus <offset> days length <duration> days".
639 * Offset and duration are optional.
640 */
641
642void HolidayParserDriverPlan::setFromEaster( int offset, int duration )
643{
644 // Don't set if only parsing metadata or calendar for event rule is not the current parse calendar
645 if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
646 return;
647 }
648
649 if ( m_eventCalendarType == QLatin1String("gregorian") ) {
650 setEvent( m_parseYearEaster.toJulianDay() + offset, 0, duration );
651 } else {
652 error( QLatin1String("Can only use Easter in Gregorian event rule") );
653 }
654}
655
656/*
657 * Set event relative to Pascha. The expression is
658 * "PASCHA plus <offset> days length <duration> days".
659 * Offset and duration are optional.
660 */
661
662void HolidayParserDriverPlan::setFromPascha( int offset, int duration )
663{
664 // Don't set if only parsing metadata or calendar for event rule is not the current parse calendar
665 if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
666 return;
667 }
668
669 if ( m_eventCalendarType == QLatin1String("gregorian") || m_eventCalendarType == QLatin1String("julian") ) {
670 setEvent( m_parseYearPascha.toJulianDay(), offset, duration );
671 } else {
672 error( QLatin1String("Can only use Pascha in Julian and Gregorian event rule") );
673 }
674}
675
676// Set the event if it falls inside the requested date range
677void HolidayParserDriverPlan::setEvent( int jd, int observeOffset, int duration )
678{
679 // Don't set if only parsing metadata or calendar for event rule is not the current parse calendar
680 if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
681 return;
682 }
683
684 // Date the holiday will be observed on
685 int observeJd = jd + observeOffset;
686
687 if ( m_multidayMode == Holiday::MultidayHolidaysAsSingleEvents ) {
688 addHoliday( QDate::fromJulianDay( observeJd ), duration );
689 } else { // KHolidays::MultidayHolidaysAsMultipleEvents
690 // Create backwards compatible holidays, one incidence per day
691 for ( int dd = 0; dd < duration; ++dd ) {
692 addHoliday( QDate::fromJulianDay( observeJd + dd ), 1 );
693 }
694 }
695}
696
697void HolidayParserDriverPlan::addHoliday( const QDate &observedDate, int duration )
698{
699 // Only set if event falls in requested date range, i.e. either starts or ends during range
700 if ( m_parseCalendar->isValid( observedDate ) &&
701 observedDate <= m_requestEnd &&
702 observedDate.addDays( duration - 1 ) >= m_requestStart ) {
703 KHolidays::Holiday holiday;
704 holiday.d->mObservedDate = observedDate;
705 holiday.d->mDuration = duration;
706 holiday.d->mText = m_eventName;
707 holiday.d->mShortText = m_eventName;
708 if ( m_eventCategories.contains( "public" ) ) {
709 holiday.d->mDayType = KHolidays::Holiday::NonWorkday;
710 } else {
711 holiday.d->mDayType = KHolidays::Holiday::Workday;
712 }
713 m_resultList.append( holiday );
714 }
715}
KHolidays::HolidayParserDriverPlan::HolidayParserDriverPlan
HolidayParserDriverPlan(const QString &planFilename)
Constructor of Plan file parser driver.
Definition: holidayparserdriverplan.cpp:53
KHolidays::HolidayParserDriverPlan::parseMetadata
void parseMetadata()
Parse the file for metadata only and populate the metadata variables.
Definition: holidayparserdriverplan.cpp:120
KHolidays::HolidayParserDriverPlan::parse
void parse()
Actually parse the file, new plan format implementation.
Definition: holidayparserdriverplan.cpp:94
KHolidays::HolidayParserDriverPlan::error
void error(const KHolidays::location &errorLocation, const QString &errorMessage)
Bison C++ skeleton error message handling.
Definition: holidayparserdriverplan.cpp:80
KHolidays::HolidayParserDriverPlan::~HolidayParserDriverPlan
~HolidayParserDriverPlan()
Destructor.
Definition: holidayparserdriverplan.cpp:72
KHolidays::HolidayParserDriver
HolidayParserDriver abstract base class.
Definition: holidayparserdriver_p.h:45
KHolidays::HolidayParserDriver::setParseStartEnd
virtual void setParseStartEnd()
Initialise parse year variables for calendar system.
Definition: holidayparserdriver.cpp:116
KHolidays::HolidayParserDriver::setParseCalendar
virtual void setParseCalendar(const QString &calendarType)
Set the calendar system to use.
Definition: holidayparserdriver.cpp:110
KHolidays::HolidayParserPlan
A Bison parser.
Definition: holidayparserplan.hpp:115
KHolidays::HolidayParserPlan::parse
virtual int parse()
Parse.
Definition: holidayparserplan.cpp:302
KHolidays::HolidayScannerPlan
HolidayScannerPlan implementation class.
Definition: holidayscannerplan_p.h:64
KHolidays::location
Abstract a location.
Definition: location.hh:57
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jul 21 2022 00:00:00 by doxygen 1.9.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KHolidays Library

Skip menu "KHolidays Library"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal