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

KHolidays Library

  • sources
  • kde-4.14
  • kdepimlibs
  • 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 
51 using namespace KHolidays;
52 
53 HolidayParserDriverPlan::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 
72 HolidayParserDriverPlan::~HolidayParserDriverPlan()
73 {
74  delete m_parser;
75  delete m_scanner;
76  delete m_fileToParse;
77 }
78 
79 //TODO Figure why it doesn't compile
80 void 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 
88 void HolidayParserDriverPlan::error( const QString &errorMessage )
89 {
90  kDebug() << errorMessage;
91 }
92 
93 
94 void 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 
120 void 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 
166 QString HolidayParserDriverPlan::filePath()
167 {
168  return m_filePath;
169 }
170 
171 std::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
181 int 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 
201 bool HolidayParserDriverPlan::isLeapYear( int year )
202 {
203  return m_parseCalendar->isLeapYear( year );
204 }
205 
206 int HolidayParserDriverPlan::parseYear()
207 {
208  return m_parseYear;
209 }
210 
211 int HolidayParserDriverPlan::monthsInYear( int year )
212 {
213  QDate tempDate;
214  m_parseCalendar->setDate( tempDate, year, 1, 1 );
215  return m_parseCalendar->monthsInYear( tempDate );
216 }
217 
218 int 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 
225 int 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 
232 void 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 
247 QDate 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 
268 QDate 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
303 int 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
314 int 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
325 int 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
336 int 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
341 int 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
365 int 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 
379 void HolidayParserDriverPlan::setFileCountryCode( const QString &countryCode )
380 {
381  m_fileCountryCode = countryCode;
382 }
383 
384 void HolidayParserDriverPlan::setFileLanguageCode( const QString &languageCode )
385 {
386  m_fileLanguageCode = languageCode;
387 }
388 
389 void HolidayParserDriverPlan::setFileName( const QString &name )
390 {
391  m_fileName = name;
392 }
393 
394 void HolidayParserDriverPlan::setFileDescription( const QString &description )
395 {
396  m_fileDescription = description;
397 }
398 
399 void 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 
406 void HolidayParserDriverPlan::setEventCategory( const QString &category )
407 {
408  m_eventCategories.append( category );
409 }
410 
411 void 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 
419 void HolidayParserDriverPlan::setEventDate( int eventYear, int eventMonth, int eventDay )
420 {
421  m_eventYear = eventYear;
422  m_eventMonth = eventMonth;
423  m_eventDay = eventDay;
424 }
425 
426 void 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 
441 void 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 
494 void 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 :-)
548 int 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 
582 void 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 
642 void 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 
662 void 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
677 void 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 
697 void 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 }
QList::clear
void clear()
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
KHolidays::HolidayParserDriver::setParseStartEnd
virtual void setParseStartEnd()
Initialise parse year variables for calendar system.
Definition: holidayparserdriver.cpp:116
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
QFile
QString::clear
void clear()
KHolidays::HolidayParserDriver
HolidayParserDriver abstract base class.
Definition: holidayparserdriver_p.h:44
KHolidays::HolidayScannerPlan
HolidayScannerPlan implementation class.
Definition: holidayscannerplan_p.h:63
KHolidays::HolidayParserPlan::set_debug_level
void set_debug_level(debug_level_type l)
Set the current debugging level.
Definition: holidayparserplan.cpp:295
QList::count
int count(const T &value) const
QList::append
void append(const T &value)
QFileInfo::fileName
QString fileName() const
QDate::toJulianDay
int toJulianDay() const
KHolidays::HolidayParserDriverPlan::parseMetadata
void parseMetadata()
Parse the file for metadata only and populate the metadata variables.
Definition: holidayparserdriverplan.cpp:120
QString::isEmpty
bool isEmpty() const
QIODevice::readAll
QByteArray readAll()
QDate
QDate::year
int year() const
QString
KHolidays::HolidayParserPlan
A Bison parser.
Definition: holidayparserplan.hpp:114
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
KHolidays::HolidayParserPlan::parse
virtual int parse()
Parse.
Definition: holidayparserplan.cpp:302
QStringList
QFileInfo
QFileInfo::exists
bool exists() const
QLatin1Char
QFile::close
virtual void close()
QLatin1String
QDate::currentDate
QDate currentDate()
KHolidays::HolidayParserDriver::setParseCalendar
virtual void setParseCalendar(const QString &calendarType)
Set the calendar system to use.
Definition: holidayparserdriver.cpp:110
KHolidays::HolidayParserDriverPlan::parse
void parse()
Actually parse the file, new plan format implementation.
Definition: holidayparserdriverplan.cpp:94
KHolidays::location
Abstract a location.
Definition: location.hh:56
QStringList::split
QStringList split(const QString &sep, const QString &str, bool allowEmptyEntries)
QByteArray::data
char * data()
QDate::addDays
QDate addDays(int ndays) const
QDate::fromJulianDay
QDate fromJulianDay(int jd)
KHolidays::HolidayParserDriverPlan::HolidayParserDriverPlan
HolidayParserDriverPlan(const QString &planFilename)
Constructor of Plan file parser driver.
Definition: holidayparserdriverplan.cpp:53
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:37:00 by doxygen 1.8.7 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 API Reference

Skip menu "kdepimlibs 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

Search



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