33 #include "holidayparserdriverplan_p.h"
34 #include "holidayscannerplan_p.h"
35 #include "holidayparserplan.hpp"
41 #include <KCalendarSystem>
44 #include "holiday_p.h"
51 using namespace KHolidays;
55 m_traceParsing( false ),
56 m_traceScanning( false ),
57 m_parseMetadataOnly( false )
59 QFile holidayFile( filePath() );
60 if ( holidayFile.
open( QIODevice::ReadOnly ) ) {
61 m_scanData = holidayFile.
readAll();
65 m_scanner->set_debug( m_traceScanning );
68 m_fileToParse =
new std::string( filePath().toLocal8Bit().data() );
82 Q_UNUSED( errorLocation );
85 kDebug() << errorMessage;
90 kDebug() << errorMessage;
97 foreach (
const QString &calendar, m_fileCalendarTypes ) {
105 for ( m_parseYear = m_parseStartYear; m_parseYear <= m_parseEndYear; ++m_parseYear ) {
107 m_parseCalendar->setDate( m_parseYearStart, m_parseYear, 1, 1 );
108 m_parseYearEaster = easter( m_parseYear );
109 m_parseYearPascha = pascha( m_parseYear );
111 std::istringstream iss2( std::string( m_scanData.
data() ) );
112 m_scanner->yyrestart( &iss2 );
122 m_parseMetadataOnly =
true;
123 m_fileCountryCode.
clear();
124 m_fileLanguageCode.
clear();
126 m_fileDescription.
clear();
127 m_fileCalendarTypes.
clear();
133 std::istringstream iss2( std::string( m_scanData.
data() ) );
134 m_scanner->yyrestart( &iss2 );
136 m_resultList.
clear();
145 if ( m_fileCountryCode.
isEmpty() ) {
146 setFileCountryCode( metadata[1].toUpper() );
148 if ( m_fileLanguageCode.
isEmpty() ) {
150 m_fileLanguageCode = language[0];
151 if ( language.
count() > 1 ) {
152 setFileLanguageCode( language[0].append(
QLatin1Char(
'_') ).append( language[1].toUpper() ) );
154 setFileLanguageCode( language[0] );
157 if ( m_fileLanguageCode.
isEmpty() && metadata.
count() > 3 ) {
158 m_fileName = metadata[3];
163 m_parseMetadataOnly =
false;
166 QString HolidayParserDriverPlan::filePath()
171 std::string *HolidayParserDriverPlan::fileToParse()
const
173 return m_fileToParse;
181 int HolidayParserDriverPlan::adjustedMonthNumber(
int month )
184 m_parseCalendar->calendarType() !=
QLatin1String(
"hebrew") ||
185 !m_parseCalendar->isLeapYear( m_parseYear ) ||
201 bool HolidayParserDriverPlan::isLeapYear(
int year )
203 return m_parseCalendar->isLeapYear( year );
206 int HolidayParserDriverPlan::parseYear()
211 int HolidayParserDriverPlan::monthsInYear(
int year )
214 m_parseCalendar->setDate( tempDate, year, 1, 1 );
215 return m_parseCalendar->monthsInYear( tempDate );
218 int HolidayParserDriverPlan::daysInMonth(
int year,
int month )
221 m_parseCalendar->setDate( tempDate, year, month, 1 );
222 return m_parseCalendar->daysInMonth( tempDate );
225 int HolidayParserDriverPlan::julianDay(
int year,
int month,
int day )
228 m_parseCalendar->setDate( tempDate, year, month, day );
232 void HolidayParserDriverPlan::julianDayToDate(
int jd,
int *year,
int *month,
int *day )
237 *year = m_parseCalendar->year( tempDate );
240 *month = m_parseCalendar->month( tempDate );
243 *day = m_parseCalendar->day( tempDate );
247 QDate HolidayParserDriverPlan::easter(
int year )
249 if ( m_parseCalendar->calendarType() !=
QLatin1String(
"gregorian") ) {
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;
261 int month = 3 + ( ( l + 40 ) / 44 );
262 int day = l + 28 - ( 31 * ( month / 4 ) );
268 QDate HolidayParserDriverPlan::pascha(
int year )
270 if ( m_parseCalendar->calendarType() ==
QLatin1String(
"gregorian") ||
271 m_parseCalendar->calendarType() ==
QLatin1String(
"julian") ) {
276 int i = ( ( 19 * g ) + 15 ) % 30;
277 int j = ( year + ( year / 4 ) + i ) % 7;
279 int month = 3 + ( ( l + 40 ) / 44 );
280 int day = l + 28 - ( 31 * ( month / 4 ) );
282 if ( m_parseCalendar->calendarType() ==
QLatin1String(
"julian") ) {
286 if ( m_parseCalendar->calendarType() ==
QLatin1String(
"gregorian") ) {
288 int paschaJd = julianDay( year, month, day );
303 int HolidayParserDriverPlan::julianDayFromEventName(
const QString &eventName )
305 foreach (
const KHolidays::Holiday &thisHoliday, m_resultList ) {
306 if ( thisHoliday.text() == eventName ) {
307 return thisHoliday.date().toJulianDay();
314 int HolidayParserDriverPlan::julianDayFromEaster(
void )
325 int HolidayParserDriverPlan::julianDayFromPascha(
void )
336 int HolidayParserDriverPlan::julianDayFromMonthDay(
int month,
int day ) {
337 return julianDay( m_parseYear, month, day );
341 int HolidayParserDriverPlan::julianDayFromRelativeWeekday(
int occurrence,
int weekday,
int jd )
343 if ( occurrence == ANY ) {
351 if ( occurrence > 0 ) {
352 occurrence = occurrence - 1;
353 }
else if ( occurrence < 0 && weekday == thisWeekday ) {
354 occurrence = occurrence + 1;
357 if ( weekday < thisWeekday ) {
358 occurrence = occurrence + 1;
361 return jd + weekday - thisWeekday + ( occurrence * 7 );
365 int HolidayParserDriverPlan::julianDayFromWeekdayInMonth(
int occurrence,
int weekday,
int month )
367 if ( occurrence == LAST ) {
368 return julianDayFromRelativeWeekday( BEFORE, weekday, julianDay( m_parseYear, month, daysInMonth( m_parseYear, month ) ) );
370 return julianDayFromRelativeWeekday( occurrence, weekday, julianDay( m_parseYear, month, 1 ) );
379 void HolidayParserDriverPlan::setFileCountryCode(
const QString &countryCode )
381 m_fileCountryCode = countryCode;
384 void HolidayParserDriverPlan::setFileLanguageCode(
const QString &languageCode )
386 m_fileLanguageCode = languageCode;
389 void HolidayParserDriverPlan::setFileName(
const QString &name )
394 void HolidayParserDriverPlan::setFileDescription(
const QString &description )
396 m_fileDescription = description;
399 void HolidayParserDriverPlan::setEventName(
const QString &eventName )
402 m_eventCategories.
clear();
403 m_eventName = eventName;
406 void HolidayParserDriverPlan::setEventCategory(
const QString &category )
408 m_eventCategories.
append( category );
411 void HolidayParserDriverPlan::setEventCalendarType(
const QString &calendarType )
413 m_eventCalendarType = calendarType;
414 if ( m_parseMetadataOnly && !m_fileCalendarTypes.
contains( calendarType ) ) {
415 m_fileCalendarTypes.
append( calendarType );
419 void HolidayParserDriverPlan::setEventDate(
int eventYear,
int eventMonth,
int eventDay )
421 m_eventYear = eventYear;
422 m_eventMonth = eventMonth;
423 m_eventDay = eventDay;
426 void HolidayParserDriverPlan::setEventDate(
int jd )
428 julianDayToDate( jd, &m_eventYear, &m_eventMonth, &m_eventDay );
441 void HolidayParserDriverPlan::setFromWeekdayInMonth(
int occurrence,
int weekday,
int month,
int offset,
int duration )
444 if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
448 int startMonth, endMonth;
449 if ( month == LAST ) {
450 startMonth = monthsInYear( m_parseYear );
451 endMonth = startMonth;
452 }
else if ( month == ANY ) {
454 endMonth = monthsInYear( m_parseYear );
461 for (
int thisMonth = startMonth; thisMonth <= endMonth; ++thisMonth ) {
463 if ( m_parseCalendar->isValid( m_parseYear, thisMonth, 1 ) ) {
464 int startOccurrence, endOccurrence;
465 if ( occurrence == ANY ) {
469 startOccurrence = occurrence;
470 endOccurrence = occurrence;
473 int jdMonthStart = julianDay( m_parseYear, thisMonth, 1 );
474 int jdMonthEnd = julianDay( m_parseYear, thisMonth, daysInMonth( m_parseYear, thisMonth ) );
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 );
494 void HolidayParserDriverPlan::setFromRelativeWeekday(
int occurrence,
int weekday,
int offset,
int duration )
497 if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
502 if ( m_eventYear == ANY ) {
503 thisYear = m_parseYear;
505 thisYear = m_eventYear;
508 int startMonth, endMonth;
509 if ( m_eventMonth == LAST ) {
510 startMonth = monthsInYear( thisYear );
511 endMonth = startMonth;
512 }
else if ( m_eventMonth == ANY ) {
514 endMonth = monthsInYear( thisYear );
516 startMonth = m_eventMonth;
517 endMonth = m_eventMonth;
522 for ( thisMonth = startMonth; thisMonth <= endMonth; ++thisMonth ) {
524 int startDay, endDay;
525 if ( m_eventDay == LAST ) {
526 startDay = daysInMonth( thisYear, thisMonth );
528 }
else if ( m_eventDay == ANY ) {
530 endDay = daysInMonth( thisYear, thisMonth );
532 startDay = m_eventDay;
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 );
548 int HolidayParserDriverPlan::conditionalOffset(
int year,
int month,
int day,
int condition )
558 m_parseCalendar->setDate( tempDate, year, month, day );
559 int weekday = m_parseCalendar->dayOfWeek( tempDate );
561 if ( condition & ( 1 << weekday ) ) {
563 int to = ( condition >> 8 );
564 while ( !( to & ( 1 << ( ( weekday + offset ) % 7 ) ) ) && ( offset < 8 ) ) {
582 void HolidayParserDriverPlan::setFromDate(
int offset,
int condition,
int duration )
585 if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
590 if ( m_eventYear == ANY ) {
591 thisYear = m_parseYear;
593 thisYear = m_eventYear;
596 int startMonth, endMonth;
597 if ( m_eventMonth == LAST ) {
598 startMonth = monthsInYear( thisYear );
599 endMonth = startMonth;
600 }
else if ( m_eventMonth == ANY ) {
602 endMonth = monthsInYear( thisYear );
604 startMonth = m_eventMonth;
605 endMonth = m_eventMonth;
609 for (
int thisMonth = startMonth; thisMonth <= endMonth; ++thisMonth ) {
611 int startDay, endDay;
612 if ( m_eventDay == LAST ) {
613 startDay = daysInMonth( thisYear, thisMonth );
615 }
else if ( m_eventDay == ANY ) {
617 endDay = daysInMonth( thisYear, thisMonth );
619 startDay = m_eventDay;
624 for (
int thisDay = startDay; thisDay <= endDay; ++thisDay ) {
626 if ( m_parseCalendar->isValid( thisYear, thisMonth, thisDay ) ) {
627 setEvent( julianDay( thisYear, thisMonth, thisDay ) + offset,
628 conditionalOffset( thisYear, thisMonth, thisDay, condition ), duration );
642 void HolidayParserDriverPlan::setFromEaster(
int offset,
int duration )
645 if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
650 setEvent( m_parseYearEaster.
toJulianDay() + offset, 0, duration );
662 void HolidayParserDriverPlan::setFromPascha(
int offset,
int duration )
665 if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
670 setEvent( m_parseYearPascha.
toJulianDay(), offset, duration );
677 void HolidayParserDriverPlan::setEvent(
int jd,
int observeOffset,
int duration )
680 if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
685 int observeJd = jd + observeOffset;
687 if ( m_multidayMode == Holiday::MultidayHolidaysAsSingleEvents ) {
691 for (
int dd = 0; dd < duration; ++dd ) {
697 void HolidayParserDriverPlan::addHoliday(
const QDate &observedDate,
int duration )
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;
711 holiday.d->mDayType = KHolidays::Holiday::Workday;
713 m_resultList.
append( holiday );
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
bool contains(const QString &str, Qt::CaseSensitivity cs) const
virtual void setParseStartEnd()
Initialise parse year variables for calendar system.
void error(const KHolidays::location &errorLocation, const QString &errorMessage)
Bison C++ skeleton error message handling.
~HolidayParserDriverPlan()
Destructor.
HolidayParserDriver abstract base class.
HolidayScannerPlan implementation class.
void set_debug_level(debug_level_type l)
Set the current debugging level.
int count(const T &value) const
void append(const T &value)
void parseMetadata()
Parse the file for metadata only and populate the metadata variables.
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
virtual int parse()
Parse.
virtual void setParseCalendar(const QString &calendarType)
Set the calendar system to use.
void parse()
Actually parse the file, new plan format implementation.
QStringList split(const QString &sep, const QString &str, bool allowEmptyEntries)
QDate addDays(int ndays) const
QDate fromJulianDay(int jd)
HolidayParserDriverPlan(const QString &planFilename)
Constructor of Plan file parser driver.