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

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