• Skip to content
  • Skip to link menu
KDE 4.5 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

KHolidays Library

holidayparserdriverplan.cpp

00001 /*
00002     Original version from plan by Thomas Driemeyer <thomas@bitrot.de>
00003 
00004     Adapted for use in KOrganizer by
00005         Preston Brown <pbrown@kde.org> and
00006         Reinhold Kainhofer <reinhold@kainhofer.com>
00007 
00008     Portions contributed by
00009         Peter Littlefield <plittle@sofkin.ca>
00010         Armin Liebl <liebla@informatik.tu-muenchen.de>
00011         Efthimios Mavrogeorgiadis <emav@enl.auth.gr>
00012         Erwin Hugo Achermann <acherman@inf.ethz.ch>
00013 
00014     Major rewrite using Bison C++ skeleton:
00015         Copyright 2010 John Layt <john@layt.net>
00016 
00017     This library is free software; you can redistribute it and/or
00018     modify it under the terms of the GNU Library General Public
00019     License as published by the Free Software Foundation; either
00020     version 2 of the License, or (at your option) any later version.
00021 
00022     This library is distributed in the hope that it will be useful,
00023     but WITHOUT ANY WARRANTY; without even the implied warranty of
00024     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025     GNU Library General Public License for more details.
00026 
00027     You should have received a copy of the GNU Library General Public License
00028     along with this library; see the file COPYING.LIB.  If not, write to the
00029     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00030     Boston, MA 02110-1301, USA.
00031 */
00032 
00033 #include "holidayparserdriverplan_p.h"
00034 #include "holidayscannerplan_p.h"
00035 #include "holidayparserplan.hpp"
00036 
00037 #include <sstream>
00038 
00039 #include <QFileInfo>
00040 
00041 #include <kdebug.h>
00042 
00043 #include "holiday_p.h"
00044 
00045 #define LAST        99999
00046 #define ANY        -99999
00047 #define BEFORE         -1
00048 #define AFTER           1
00049 
00050 using namespace KHolidays;
00051 
00052 HolidayParserDriverPlan::HolidayParserDriverPlan( const QString &planFilePath )
00053                         :HolidayParserDriver( planFilePath ),
00054                         m_traceParsing( false ),
00055                         m_traceScanning( false )
00056 {
00057     QFile holidayFile( filePath() );
00058     if ( holidayFile.open( QIODevice::ReadOnly ) ) {
00059         m_scanData = holidayFile.readAll();
00060         holidayFile.close();
00061     }
00062     m_scanner = new HolidayScannerPlan();
00063     m_scanner->set_debug( m_traceScanning );
00064     m_parser = new HolidayParserPlan( *this );
00065     m_parser->set_debug_level( m_traceParsing );
00066     parseMetadata();
00067 }
00068 
00069 HolidayParserDriverPlan::~HolidayParserDriverPlan()
00070 {
00071     delete m_parser;
00072     delete m_scanner;
00073 }
00074 
00075 //TODO Figure why it doesn't compile
00076 void HolidayParserDriverPlan::error( const KHolidays::location &errorLocation, const QString &errorMessage )
00077 {
00078   Q_UNUSED( errorLocation );
00079   //std::cerr << errorLocation << " : " << errorMessage;  //Doesn't work???
00080   //kDebug() << errorLocation << " : " << errorMessage;  //Doesn't work???
00081   kDebug() << errorMessage;
00082 }
00083 
00084 void HolidayParserDriverPlan::error( const QString &errorMessage )
00085 {
00086     kDebug() << errorMessage;
00087 }
00088 
00089 
00090 void HolidayParserDriverPlan::parse()
00091 {
00092     // Parse the file using every available calendar system, even if not defined in file
00093     // TODO this will not scale as more systems are added over time, either move to AST model
00094     //      or have this driven via pre-scan or file metadata to determine requied calendar systems
00095     foreach( QString calendar, KCalendarSystem::calendarSystems() ) {
00096 
00097         // Cater for events defined in other Calendar Systems where request year could cover 2 or 3 event years
00098         // Perhaps also parse year before and year after to allow events to span years or shift to other year?
00099         setParseCalendar( calendar );
00100         setParseStartEnd();
00101 
00102         // Generate all events for this calendar in the required year(s)
00103         for ( m_parseYear = m_parseStartYear; m_parseYear <= m_parseEndYear; ++m_parseYear ) {
00104 
00105             m_parseCalendar->setDate( m_parseYearStart, m_parseYear, 1, 1 );
00106             m_parseYearEaster = easter( m_parseYear );
00107             m_parseYearPascha = pascha( m_parseYear );
00108 
00109             std::istringstream iss2( std::string( m_scanData.data() ) );
00110             m_scanner->yyrestart( &iss2 );
00111 
00112             m_parser->parse();
00113         }
00114 
00115     }
00116 }
00117 
00118 void HolidayParserDriverPlan::parseMetadata()
00119 {
00120     m_fileCountryCode.clear();
00121     m_fileLanguageCode.clear();
00122     m_fileName.clear();
00123     m_fileDescription.clear();
00124 
00125     // Default to files internal metadata
00126     setParseCalendar( "gregorian" );
00127     m_parseYear = QDate::currentDate().year();
00128     std::istringstream iss2( std::string( m_scanData.data() ) );
00129     m_scanner->yyrestart( &iss2 );
00130     m_parser->parse();
00131     m_resultList.clear();
00132 
00133     // If not populated, then use filename metadata, this may change later
00134     // metadata is encoded in filename in form holiday_<region>_<type>_<language>_<name>
00135     // with region, type and language sub groups separated by -, and with name optional
00136     QFileInfo file( m_filePath );
00137     if ( file.exists() ) {
00138         QStringList metadata = file.fileName().split('_');
00139         if ( metadata[0] == "holiday" && metadata.count() > 2 ) {
00140             if ( m_fileCountryCode.isEmpty() ) {
00141                 setFileCountryCode( metadata[1].toUpper() );
00142             }
00143             if ( m_fileLanguageCode.isEmpty() ) {
00144                 QStringList language = metadata[2].split('-');
00145                 m_fileLanguageCode = language[0];
00146                 if ( language.count() > 1 ) {
00147                     setFileLanguageCode( language[0].append( '_' ).append( language[1].toUpper() ) );
00148                 } else {
00149                   setFileLanguageCode( language[0] );
00150                 }
00151             }
00152             if ( m_fileLanguageCode.isEmpty() && metadata.count() > 3 ) {
00153                 m_fileName = metadata[3];
00154             }
00155         }
00156     }
00157 
00158 
00159 }
00160 
00161 QString HolidayParserDriverPlan::filePath()
00162 {
00163     return m_filePath;
00164 }
00165 
00166 
00167 /*****************************************
00168   Calendar and Date convenience routines
00169 ******************************************/
00170 
00171 // Adjust month numbering for Hebrew civil calendar leap month
00172 int HolidayParserDriverPlan::adjustedMonthNumber( int month )
00173 {
00174     if ( m_eventCalendarType != "hebrew" ||              // Only adjust Hebrew months
00175          m_parseCalendar->calendarType() != "hebrew" ||
00176          !m_parseCalendar->isLeapYear( m_parseYear ) ||  // Only adjust in leap year
00177          month < 6 ) {                                   // Only adjust from Adar onwards
00178         return month;
00179     }
00180 
00181     if ( month == 13 ) { // Adar I
00182         return 6;
00183     }
00184 
00185     if ( month == 14 ) { // Adar II
00186       return 7;
00187     }
00188 
00189     return month + 1; // Inserting Adar I moves other months up by 1
00190 }
00191 
00192 bool HolidayParserDriverPlan::isLeapYear( int year )
00193 {
00194     return m_parseCalendar->isLeapYear( year );
00195 }
00196 
00197 int HolidayParserDriverPlan::parseYear()
00198 {
00199     return m_parseYear;
00200 }
00201 
00202 int HolidayParserDriverPlan::monthsInYear( int year )
00203 {
00204     QDate tempDate;
00205     m_parseCalendar->setDate( tempDate, year, 1, 1 );
00206     return m_parseCalendar->monthsInYear( tempDate );
00207 }
00208 
00209 int HolidayParserDriverPlan::daysInMonth( int year, int month )
00210 {
00211     QDate tempDate;
00212     m_parseCalendar->setDate( tempDate, year, month, 1 );
00213     return m_parseCalendar->daysInMonth( tempDate );
00214 }
00215 
00216 int HolidayParserDriverPlan::julianDay( int year, int month, int day )
00217 {
00218     QDate tempDate;
00219     m_parseCalendar->setDate( tempDate, year, month, day );
00220     return tempDate.toJulianDay();
00221 }
00222 
00223 void HolidayParserDriverPlan::julianDayToDate( int jd, int *year, int *month, int *day )
00224 {
00225     QDate tempDate = QDate::fromJulianDay( jd );
00226 
00227     if ( year ) {
00228         *year = m_parseCalendar->year( tempDate );
00229     }
00230     if ( month ) {
00231         *month = m_parseCalendar->month( tempDate );
00232     }
00233     if ( day ) {
00234         *day = m_parseCalendar->day( tempDate );
00235     }
00236 }
00237 
00238 QDate HolidayParserDriverPlan::easter( int year )
00239 {
00240     if ( m_parseCalendar->calendarType() != "gregorian" ) {
00241         return QDate();
00242     }
00243 
00244     // Algorithm taken from Tondering
00245     // http://www.tondering.dk/claus/cal/node3.html#SECTION003137000000000000000
00246     int g = year % 19;
00247     int c = year / 100;
00248     int h = ( c - ( c / 4 ) - ( ( ( 8 * c ) - 13 ) / 25 ) + ( 19 * g ) + 15 ) % 30;
00249     int i = h - ( ( h / 28 ) * ( 1 - ( ( 29 / ( h + 1 ) ) * ( ( 21 - g ) / 11 ) ) ) );
00250     int j = ( year + ( year / 4 ) + i + 2 - c + ( c / 4 ) ) % 7;
00251     int l = i - j;
00252     int month = 3 + ( ( l + 40 ) / 44 );
00253     int day = l + 28 - ( 31 * ( month / 4 ) );
00254 
00255     return QDate::fromJulianDay( julianDay( year, month, day ) );
00256 }
00257 
00258 
00259 QDate HolidayParserDriverPlan::pascha( int year )
00260 {
00261     if ( m_parseCalendar->calendarType() == "gregorian" ||
00262          m_parseCalendar->calendarType() == "julian" ) {
00263         // Algorithm taken from Tondering
00264         // http://www.tondering.dk/claus/cal/node3.html#SECTION003137000000000000000
00265         // Gives Orthodox Easter in the Julian Calendar, need to convert afterwards to Gregorian if needed
00266         int g = year % 19;
00267         int i = ( ( 19 * g ) + 15 ) % 30;
00268         int j = ( year + ( year / 4 ) + i ) % 7;
00269         int l = i - j;
00270         int month = 3 + ( ( l + 40 ) / 44 );
00271         int day = l + 28 - ( 31 * ( month / 4 ) );
00272 
00273         if ( m_parseCalendar->calendarType() == "julian" ) {
00274             return QDate::fromJulianDay( julianDay( year, month, day ) );
00275         }
00276 
00277         if ( m_parseCalendar->calendarType() == "gregorian" ) {
00278             setParseCalendar( "julian" );
00279             int paschaJd = julianDay( year, month, day );
00280             setParseCalendar( "gregorian" );
00281             return QDate::fromJulianDay( paschaJd );
00282         }
00283     }
00284 
00285     return QDate();
00286 }
00287 
00288 
00289 /*************************
00290  * Calculate jd routines *
00291  *************************/
00292 
00293 // Return the jd of an existing event, assumes unique names and correct order in file
00294 int HolidayParserDriverPlan::julianDayFromEventName( const QString &eventName )
00295 {
00296     foreach ( const KHolidays::Holiday &thisHoliday, m_resultList ) {
00297         if ( thisHoliday.text() == eventName ) {
00298             return thisHoliday.date().toJulianDay();
00299         }
00300     }
00301     return -1;
00302 }
00303 
00304 // Return jd of Easter if Gregorian
00305 int HolidayParserDriverPlan::julianDayFromEaster( void )
00306 {
00307     if ( m_eventCalendarType == "gregorian" ) {
00308         return m_parseYearEaster.toJulianDay();
00309     } else {
00310         error( "Can only use Easter in Gregorian event rule" );
00311         return -1;
00312     }
00313 }
00314 
00315 // Return jd of Orthodox Easter if Gregorian or Julian
00316 int HolidayParserDriverPlan::julianDayFromPascha( void )
00317 {
00318     if ( m_eventCalendarType == "gregorian" || m_eventCalendarType == "julian" ) {
00319         return m_parseYearPascha.toJulianDay();
00320     } else {
00321         error( "Can only use Easter in Gregorian or Julian event rule" );
00322         return -1;
00323     }
00324 }
00325 
00326 // Return jd of weekday from a month/day in parse year
00327 int HolidayParserDriverPlan::julianDayFromMonthDay( int month, int day ) {
00328     return julianDay( m_parseYear, month, day );
00329 }
00330 
00331 // Return jd of weekday relative to a Julian Day number
00332 int HolidayParserDriverPlan::julianDayFromRelativeWeekday( int occurrence, int weekday, int jd )
00333 {
00334     if ( occurrence == ANY ) {  /* Should never get this, convert to AFTER instead */
00335         occurrence = AFTER;
00336     }
00337 
00338     int thisWeekday = m_parseCalendar->dayOfWeek( QDate::fromJulianDay( jd ) );
00339 
00340     /* AFTER actually means on or after */
00341     /* BEFORE actually means on or before */
00342     if ( occurrence > 0 ) {
00343         occurrence = occurrence - 1;
00344     } else if ( occurrence < 0 && weekday == thisWeekday ) {
00345         occurrence = occurrence + 1;
00346     }
00347 
00348     if ( weekday < thisWeekday ) {
00349         occurrence = occurrence + 1;
00350     }
00351 
00352     return jd + weekday - thisWeekday + ( occurrence * 7 );
00353 }
00354 
00355 // Return jd of weekday occurence in a given month and day in the parse year
00356 int HolidayParserDriverPlan::julianDayFromWeekdayInMonth( int occurrence, int weekday, int month )
00357 {
00358     if ( occurrence == LAST ) {  // Is weekday on or before last day of month
00359         return julianDayFromRelativeWeekday( BEFORE, weekday, julianDay( m_parseYear, month, daysInMonth( m_parseYear, month ) ) );
00360     } else {  // Is nth weekday on or after first day of month
00361         return julianDayFromRelativeWeekday( occurrence, weekday, julianDay( m_parseYear, month, 1 ) );
00362     }
00363 }
00364 
00365 
00366 /****************************************************
00367  * Set parsed event variables convenience functions *
00368  ****************************************************/
00369 
00370 void  HolidayParserDriverPlan::setFileCountryCode( const QString &countryCode )
00371 {
00372     m_fileCountryCode = countryCode;
00373 }
00374 
00375 void  HolidayParserDriverPlan::setFileLanguageCode( const QString &languageCode )
00376 {
00377     m_fileLanguageCode = languageCode;
00378 }
00379 
00380 void  HolidayParserDriverPlan::setFileName( const QString &name )
00381 {
00382     m_fileName = name;
00383 }
00384 
00385 void  HolidayParserDriverPlan::setFileDescription( const QString &description )
00386 {
00387     m_fileDescription = description;
00388 }
00389 
00390 void  HolidayParserDriverPlan::setEventName( const QString &eventName )
00391 {
00392     m_eventName = eventName;
00393 }
00394 
00395 void  HolidayParserDriverPlan::setEventColorName( int nameColor )
00396 {
00397     m_eventColorName = nameColor;
00398 }
00399 
00400 void  HolidayParserDriverPlan::setEventColorDay( int dayColor )
00401 {
00402     m_eventColorDay = dayColor;
00403 }
00404 
00405 void  HolidayParserDriverPlan::setEventCalendarType( const QString &calendarType )
00406 {
00407   m_eventCalendarType = calendarType;
00408 }
00409 
00410 void  HolidayParserDriverPlan::setEventDate( int eventYear, int eventMonth, int eventDay )
00411 {
00412     m_eventYear = eventYear;
00413     m_eventMonth = eventMonth;
00414     m_eventDay = eventDay;
00415 }
00416 
00417 void  HolidayParserDriverPlan::setEventDate( int jd )
00418 {
00419     julianDayToDate( jd, &m_eventYear, &m_eventMonth, &m_eventDay );
00420 }
00421 
00422 /********************************************
00423  * Set event date from event rules routines *
00424  ********************************************/
00425 
00426 /*
00427  * Set event by weekday (Monday..Sunday). The rule expression is
00428  * "every <occurrence> <weekday> of <month> plus <offset> days length <duration> days".
00429  * Occurrence and month can be ANY or LAST, offset and duration are optional.
00430  */
00431 
00432 void HolidayParserDriverPlan::setFromWeekdayInMonth( int occurrence, int weekday, int month, int offset, int duration )
00433 {
00434     // Don't set if calendar for event rule is not the current parse calendar
00435     if ( m_eventCalendarType != m_parseCalendar->calendarType() ) {
00436         return;
00437     }
00438 
00439     int startMonth, endMonth;
00440     if ( month == LAST ) {
00441         startMonth = monthsInYear( m_parseYear );
00442         endMonth = startMonth;
00443     } else if ( month == ANY ) {
00444         startMonth = 1;
00445         endMonth = monthsInYear( m_parseYear );
00446     } else {
00447         startMonth = month;
00448         endMonth = month;
00449     }
00450 
00451     // Generate all events in the required event month(s)
00452     for ( int thisMonth = startMonth; thisMonth <= endMonth; ++thisMonth ) {
00453 
00454         if ( m_parseCalendar->isValid( m_parseYear, thisMonth, 1 ) ) {
00455             int startOccurrence, endOccurrence;
00456             if ( occurrence == ANY ) {  // Generate 1st through 5th weekdays, assumes no month with > 35 days
00457                 startOccurrence = 1;
00458                 endOccurrence = 5;
00459             } else {  // Generate just nth or LAST weekday
00460                 startOccurrence = occurrence;
00461                 endOccurrence = occurrence;
00462             }
00463 
00464             int jdMonthStart = julianDay( m_parseYear, thisMonth, 1 );
00465             int jdMonthEnd = julianDay( m_parseYear, thisMonth, daysInMonth( m_parseYear, thisMonth ) );
00466 
00467             // Generate each required occurrence of weekday in month, check occurrence actually falls in month
00468             for ( int thisOccurrence = startOccurrence; thisOccurrence <= endOccurrence; ++thisOccurrence ) {
00469                 int thisJd = julianDayFromWeekdayInMonth( thisOccurrence, weekday, thisMonth );
00470                 if ( thisJd >= jdMonthStart && thisJd <= jdMonthEnd ) {
00471                     setEvent( thisJd + offset, 0, duration );
00472                 }
00473             }
00474         }
00475 
00476     }
00477 }
00478 
00479 /*
00480  * Set event by weekday (Monday..Sunday) relative to a date. The expression is
00481  * "<weekday> <occurrence> <date> plus <offset> days length <duration> days".
00482  * Occurrence, month and day can be ANY or LAST, year can be ANY, offset and duration are optional.
00483  */
00484 
00485 void HolidayParserDriverPlan::setFromRelativeWeekday( int occurrence, int weekday, int offset, int duration )
00486 {
00487     // Don't set if calendar for event rule is not the current parse calendar
00488     if ( m_eventCalendarType != m_parseCalendar->calendarType() ) {
00489         return;
00490     }
00491 
00492     int thisYear;
00493     if ( m_eventYear == ANY ) {  // Generate the parse year
00494         thisYear = m_parseYear;
00495     } else {  // Generate a specific event year
00496         thisYear = m_eventYear;
00497     }
00498 
00499     int startMonth, endMonth;
00500     if ( m_eventMonth == LAST ) {  // Generate just the last month
00501         startMonth = monthsInYear( thisYear );
00502         endMonth = startMonth;
00503     } else if ( m_eventMonth == ANY ) {  // Generate every month
00504         startMonth = 1;
00505         endMonth = monthsInYear( thisYear );
00506     } else {  // Generate just the specific event month
00507         startMonth = m_eventMonth;
00508         endMonth = m_eventMonth;
00509     }
00510 
00511     // Generate all events in the required month(s)
00512     int thisMonth;
00513     for ( thisMonth = startMonth; thisMonth <= endMonth; ++thisMonth ) {
00514 
00515         int startDay, endDay;
00516         if ( m_eventDay == LAST ) {  // Generate just the last day in the month
00517             startDay = daysInMonth( thisYear, thisMonth );
00518             endDay = startDay;
00519         } else if ( m_eventDay == ANY ) {  // Generate every day in the month
00520             startDay = 1;
00521             endDay = daysInMonth( thisYear, thisMonth );
00522         } else {  // Generate just the specific event day
00523             startDay = m_eventDay;
00524             endDay = m_eventDay;
00525         }
00526 
00527         // Generate all events on the required day(s)
00528         for ( int thisDay = startDay; thisDay <= endDay; ++thisDay ) {
00529             if ( m_parseCalendar->isValid( thisYear, thisMonth, thisDay ) ) {
00530                 int relativeJd = julianDayFromRelativeWeekday( occurrence, weekday, julianDay( thisYear, thisMonth, thisDay ) );
00531                 setEvent( relativeJd + offset, 0, duration );
00532             }
00533         }
00534 
00535     }
00536 }
00537 
00538 // TODO Figure out how this works :-)
00539 int HolidayParserDriverPlan::conditionalOffset( int year, int month, int day, int condition )
00540 {
00546     int offset = 0;
00547 
00548     QDate tempDate;
00549     m_parseCalendar->setDate( tempDate, year, month, day );
00550     int weekday = m_parseCalendar->dayOfWeek( tempDate );
00551 
00552     if ( condition & ( 1 << weekday ) ) {
00553         /* condition matches -> higher 8 bits contain the possible days to shift to */
00554         int to = ( condition >> 8 );
00555         while ( !( to & ( 1 << ( ( weekday + offset ) % 7 ) ) ) && ( offset < 8 ) ) {
00556             ++offset;
00557         }
00558     }
00559 
00560     if ( offset >= 8 ) {
00561         offset = 0;
00562     }
00563 
00564     return offset;
00565 }
00566 
00567 /*
00568  * Set event by date. The expression is
00569  * "<date> plus <offset> days shift <condition> length <duration> days".
00570  * Occurrence, month and day can be ANY or LAST, year can be ANY, offset and duration are optional.
00571  */
00572 
00573 void HolidayParserDriverPlan::setFromDate( int offset, int condition, int duration )
00574 {
00575     // Don't set if calendar for event rule is not the current parse calendar
00576     if ( m_eventCalendarType != m_parseCalendar->calendarType() ) {
00577         return;
00578     }
00579 
00580     int thisYear;
00581     if ( m_eventYear == ANY ) {  // Generate the parse year
00582         thisYear = m_parseYear;
00583     } else {  // Generate a specific event year
00584         thisYear = m_eventYear;
00585     }
00586 
00587     int startMonth, endMonth;
00588     if ( m_eventMonth == LAST ) {  // Generate just the last month
00589         startMonth = monthsInYear( thisYear );
00590         endMonth = startMonth;
00591     } else if ( m_eventMonth == ANY ) {  // Generate every month
00592         startMonth = 1;
00593         endMonth = monthsInYear( thisYear );
00594     } else {  // Generate just the specific event month
00595         startMonth = m_eventMonth;
00596         endMonth = m_eventMonth;
00597     }
00598 
00599     // Generate all events in the required month(s)
00600     for ( int thisMonth = startMonth; thisMonth <= endMonth; ++thisMonth ) {
00601 
00602         int startDay, endDay;
00603         if ( m_eventDay == LAST ) {  // Generate just the last day in the month
00604             startDay = daysInMonth( thisYear, thisMonth );
00605             endDay = startDay;
00606         } else if ( m_eventDay == ANY ) {  // Generate every day in the month
00607             startDay = 1;
00608             endDay = daysInMonth( thisYear, thisMonth );
00609         } else {  // Generate just the specific event day
00610             startDay = m_eventDay;
00611             endDay = m_eventDay;
00612         }
00613 
00614         // Generate all events on the required day(s)
00615         for ( int thisDay = startDay; thisDay <= endDay; ++thisDay ) {
00616 
00617             if ( m_parseCalendar->isValid( thisYear, thisMonth, thisDay ) ) {
00618                 setEvent( julianDay( thisYear, thisMonth, thisDay ) + offset,
00619                           conditionalOffset( thisYear, thisMonth, thisDay, condition ), duration );
00620             }
00621 
00622         }
00623 
00624     }
00625 }
00626 
00627 /*
00628  * Set event relative to Easter. The expression is
00629  * "EASTER plus <offset> days length <duration> days".
00630  * Offset and duration are optional.
00631  */
00632 
00633 void HolidayParserDriverPlan::setFromEaster( int offset, int duration )
00634 {
00635     // Don't set if calendar for event rule is not the current parse calendar
00636     if ( m_eventCalendarType != m_parseCalendar->calendarType() ) {
00637         return;
00638     }
00639 
00640     if ( m_eventCalendarType == "gregorian" ) {
00641         setEvent( m_parseYearEaster.toJulianDay() + offset, 0, duration );
00642     } else {
00643         error( "Can only use Easter in Gregorian event rule" );
00644     }
00645 }
00646 
00647 /*
00648  * Set event relative to Pascha. The expression is
00649  * "PASCHA plus <offset> days length <duration> days".
00650  * Offset and duration are optional.
00651  */
00652 
00653 void HolidayParserDriverPlan::setFromPascha( int offset, int duration )
00654 {
00655     // Don't set if calendar for event rule is not the current parse calendar
00656     if ( m_eventCalendarType != m_parseCalendar->calendarType() ) {
00657         return;
00658     }
00659 
00660     if ( m_eventCalendarType == "gregorian" || m_eventCalendarType == "julian" ) {
00661         setEvent( m_parseYearPascha.toJulianDay(), offset, duration );
00662     } else {
00663         error( "Can only use Pascha in Julian and Gregorian event rule" );
00664     }
00665 }
00666 
00667 // Set the event if it falls inside the requested date range
00668 void HolidayParserDriverPlan::setEvent( int jd, int observeOffset, int duration )
00669 {
00670     // Don't set if calendar for event rule is not the current parse calendar
00671     if ( m_eventCalendarType != m_parseCalendar->calendarType() ) {
00672         return;
00673     }
00674 
00675     // Date the holiday will be observed on
00676     int observeJd = jd + observeOffset;
00677 
00678     // Create entries compatible with old parser for now
00679     for ( int dd = 0; dd < duration; ++dd ) {
00680 
00681         // Only set if event falls in requested date range
00682         if ( m_parseCalendar->isValid( QDate::fromJulianDay( observeJd + dd ) ) &&
00683              observeJd + dd >= m_requestStart.toJulianDay() &&
00684              observeJd + dd <= m_requestEnd.toJulianDay() ) {
00685 
00686             KHolidays::Holiday holiday;
00687             holiday.d->mDate = QDate::fromJulianDay( observeJd + dd );
00688             holiday.d->mText = m_eventName;
00689             holiday.d->mShortText = m_eventName;
00690             if ( m_eventColorName == 2 || m_eventColorName == 9 ||
00691                 m_eventColorDay == 2 || m_eventColorDay == 9 ) {
00692                 holiday.d->mDayType = KHolidays::Holiday::NonWorkday;
00693             } else {
00694                 holiday.d->mDayType = KHolidays::Holiday::Workday;
00695             }
00696             m_resultList.append( holiday );
00697 
00698         }
00699 
00700     }
00701 }

KHolidays Library

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.7.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal