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

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