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

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