00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "holidayregion.h"
00026
00027 #include <QtCore/QDateTime>
00028 #include <QtCore/QFile>
00029 #include <QtCore/QSharedData>
00030 #include <QtCore/QFileInfo>
00031
00032 #include <KStandardDirs>
00033 #include <KGlobal>
00034 #include <KLocale>
00035 #include <KDebug>
00036
00037 #include "holiday_p.h"
00038 #include "parsers/plan2/holidayparserdriverplan_p.h"
00039
00040 using namespace KHolidays;
00041
00042 class HolidayRegion::Private
00043 {
00044 public:
00045 Private( const QString ®ionCode ) : mDriver( 0 ),
00046 mRegionCode( regionCode )
00047 {
00048 if ( !mRegionCode.isEmpty() ) {
00049
00050 if ( mRegionCode.length() == 2 ) {
00051 mLocation = mRegionCode;
00052 QStringList locationFiles = KGlobal::dirs()->findAllResources( "data",
00053 "libkholidays/plan2/holiday_" + mLocation + '*',
00054 KStandardDirs::NoDuplicates );
00055 if ( locationFiles.count() > 0 ) {
00056 mRegionCode = locationFiles.at( 0 )
00057 .mid( locationFiles.at( 0 ).lastIndexOf( "holiday_" ) + 8 );
00058 }
00059 }
00060
00061 mHolidayFile.setFile( KStandardDirs::locate( "data", "libkholidays/plan2/holiday_" + mRegionCode ) );
00062 }
00063
00064 init();
00065 }
00066
00067 Private( const QFileInfo ®ionFile ) : mDriver( 0 ),
00068 mHolidayFile( regionFile )
00069 {
00070 init();
00071 }
00072
00073 ~Private()
00074 {
00075 delete mDriver;
00076 }
00077
00078 void init()
00079 {
00080 if ( mHolidayFile.exists() ) {
00081 mDriver = new HolidayParserDriverPlan( mHolidayFile.absoluteFilePath() );
00082 if ( mDriver ) {
00083
00084 if ( mLocation.isEmpty() ) {
00085 mLocation = mDriver->fileCountryCode().left( 2 );
00086 }
00087
00088 if ( mRegionCode.isEmpty() ) {
00089 if ( mHolidayFile.fileName().startsWith( QLatin1String( "holiday_" ) ) ) {
00090 mRegionCode = mHolidayFile.fileName().mid( 8 );
00091 } else {
00092 mRegionCode = mHolidayFile.fileName();
00093 }
00094 }
00095
00096 } else {
00097 mRegionCode.clear();
00098 mLocation.clear();
00099 }
00100 } else {
00101 mRegionCode.clear();
00102 mLocation.clear();
00103 }
00104 }
00105
00106 HolidayParserDriver *mDriver;
00107 QString mRegionCode;
00108 QString mLocation;
00109 QFileInfo mHolidayFile;
00110 };
00111
00112 HolidayRegion::HolidayRegion( const QString ®ionCode )
00113 : d( new Private( regionCode ) )
00114 {
00115 }
00116
00117 HolidayRegion::HolidayRegion( const QFileInfo ®ionFile )
00118 : d( new Private( regionFile ) )
00119 {
00120 }
00121
00122 HolidayRegion::~HolidayRegion()
00123 {
00124 delete d;
00125 }
00126
00127 QStringList HolidayRegion::locations()
00128 {
00129 const QStringList files =
00130 KGlobal::dirs()->findAllResources( "data", "libkholidays/plan2/holiday_*",
00131 KStandardDirs::NoDuplicates );
00132
00133 QStringList locations;
00134 foreach ( const QString &filename, files ) {
00135 locations.append( filename.mid( filename.lastIndexOf( "holiday_" ) + 8, 2 ) );
00136 }
00137
00138 locations.removeDuplicates();
00139 qSort( locations );
00140 return locations;
00141 }
00142
00143 QString HolidayRegion::location() const
00144 {
00145 return d->mLocation;
00146 }
00147
00148 QStringList HolidayRegion::regionCodes()
00149 {
00150 const QStringList files =
00151 KGlobal::dirs()->findAllResources( "data", "libkholidays/plan2/holiday_*",
00152 KStandardDirs::NoDuplicates );
00153
00154 QStringList regionCodesList;
00155 foreach ( const QString &filename, files ) {
00156 regionCodesList.append( filename.mid( filename.lastIndexOf( "holiday_" ) + 8 ) );
00157 }
00158
00159 qSort( regionCodesList );
00160 return regionCodesList;
00161 }
00162
00163 QString HolidayRegion::regionCode() const
00164 {
00165 return d->mRegionCode;
00166 }
00167
00168 QString HolidayRegion::countryCode() const
00169 {
00170 return d->mDriver->fileCountryCode();
00171 }
00172
00173 QString HolidayRegion::countryCode( const QString ®ionCode )
00174 {
00175 HolidayRegion temp = HolidayRegion( regionCode );
00176 if ( temp.isValid() ) {
00177 return temp.countryCode();
00178 } else {
00179 return QString();
00180 }
00181 }
00182
00183 QString HolidayRegion::languageCode() const
00184 {
00185 return d->mDriver->fileLanguageCode();
00186 }
00187
00188 QString HolidayRegion::languageCode( const QString ®ionCode )
00189 {
00190 HolidayRegion temp = HolidayRegion( regionCode );
00191 if ( temp.isValid() ) {
00192 return temp.languageCode();
00193 } else {
00194 return QString();
00195 }
00196 }
00197
00198 QString HolidayRegion::name() const
00199 {
00200 QString tempName = d->mDriver->fileName();
00201
00202 if ( tempName.isEmpty() ) {
00203 QStringList countryParts = countryCode().toLower().split( '-' );
00204 QString country = countryParts.at( 0 );
00205 QString regionName, typeName;
00206
00207 if ( country != "xx" ) {
00208 if ( countryParts.count() == 2 ) {
00209
00210
00211 QString subdivision = countryParts.at( 1 );
00212 if ( country == "ca" && subdivision == "qc" ) {
00213 regionName = i18nc( "Canadian region", "Quebec" );
00214 } else if ( country == "de" && subdivision == "by" ) {
00215 regionName = i18nc( "German region", "Bavaria" );
00216 } else if ( country == "es" && subdivision == "ct" ) {
00217 regionName = i18nc( "Spanish region", "Catalonia" );
00218 } else if ( country == "gb" && subdivision == "eaw" ) {
00219 regionName = i18nc( "UK Region", "England and Wales" );
00220 } else if ( country == "gb" && subdivision == "eng" ) {
00221 regionName = i18nc( "UK Region", "England" );
00222 } else if ( country == "gb" && subdivision == "wls" ) {
00223 regionName = i18nc( "UK Region", "Wales" );
00224 } else if ( country == "gb" && subdivision == "sct" ) {
00225 regionName = i18nc( "UK Region", "Scotland" );
00226 } else if ( country == "gb" && subdivision == "nir" ) {
00227 regionName = i18nc( "UK Region", "Northern Ireland" );
00228 } else if ( country == "it" && subdivision == "bz" ) {
00229 regionName = i18nc( "Italian Region", "South Tyrol" );
00230 } else if ( country == "au" && subdivision == "nsw" ) {
00231 regionName = i18nc( "Australian Region", "New South Wales" );
00232 } else if ( country == "au" && subdivision == "qld" ) {
00233 regionName = i18nc( "Australian Region", "Queensland" );
00234 } else if ( country == "au" && subdivision == "vic" ) {
00235 regionName = i18nc( "Australian Region", "Victoria" );
00236 } else if ( country == "au" && subdivision == "sa" ) {
00237 regionName = i18nc( "Australian Region", "South Australia" );
00238 } else if ( country == "au" && subdivision == "nt" ) {
00239 regionName = i18nc( "Australian Region", "Northern Territory" );
00240 } else if ( country == "au" && subdivision == "act" ) {
00241 regionName = i18nc( "Australian Region", "Australian Capital Territory" );
00242 } else if ( country == "au" && subdivision == "wa" ) {
00243 regionName = i18nc( "Australian Region", "Western Australia" );
00244 } else if ( country == "au" && subdivision == "tas" ) {
00245 regionName = i18nc( "Australian Region", "Tasmania" );
00246 } else {
00247 regionName = KGlobal::locale()->countryCodeToName( country );
00248 }
00249 } else {
00250 regionName = KGlobal::locale()->countryCodeToName( country );
00251 }
00252 }
00253
00254
00255 QStringList regionParts = regionCode().toLower().split( '_' );
00256 if ( regionParts.count() == 3 ) {
00257 QString type = regionParts.at( 2 );
00258
00259
00260 if ( type == "public" ) {
00261 typeName = i18nc( "Holiday type", "Public" );
00262 } else if ( type == "religious" ) {
00263 typeName = i18nc( "Holiday type", "Religious" );
00264 } else if ( type == "financial" ) {
00265 typeName = i18nc( "Holiday type", "Financial" );
00266 } else if ( type == "cultural" ) {
00267 typeName = i18nc( "Holiday type", "Cultural" );
00268 } else if ( type == "school" ) {
00269 typeName = i18nc( "Holiday type", "School" );
00270 } else if ( type == "seasons" ) {
00271 typeName = i18nc( "Holiday type", "Seasons" );
00272 } else if ( type == "name" ) {
00273 typeName = i18nc( "Holiday type", "Name Days" );
00274 } else if ( type == "personal" ) {
00275 typeName = i18nc( "Holiday type", "Personal" );
00276 } else if ( type == "catholic" ) {
00277 typeName = i18nc( "Holiday type", "Catholic" );
00278 } else if ( type == "protestant" ) {
00279 typeName = i18nc( "Holiday type", "Protestant" );
00280 } else if ( type == "orthodox" ) {
00281 typeName = i18nc( "Holiday type", "Orthodox" );
00282 } else if ( type == "jewish" ) {
00283 typeName = i18nc( "Holiday type", "Jewish" );
00284 } else if ( type == "islamic" ) {
00285 typeName = i18nc( "Holiday type", "Islamic" );
00286 }
00287 }
00288
00289 if ( !regionName.isEmpty() ) {
00290 if ( !typeName.isEmpty() ) {
00291
00292 tempName = QString( "%1 - %2" ).arg( regionName ).arg( typeName );
00293 } else {
00294 tempName = regionName;
00295 }
00296 } else if ( !typeName.isEmpty() ) {
00297 tempName = typeName;
00298 } else {
00299 tempName = i18nc( "Unknown holiday region", "Unknown" );
00300 }
00301 }
00302 return tempName;
00303 }
00304
00305 QString HolidayRegion::name( const QString ®ionCode )
00306 {
00307 HolidayRegion temp = HolidayRegion( regionCode );
00308 if ( temp.isValid() ) {
00309 return temp.name();
00310 } else {
00311 return QString();
00312 }
00313 }
00314
00315 QString HolidayRegion::description() const
00316 {
00317 return d->mDriver->fileDescription();
00318 }
00319
00320 QString HolidayRegion::description( const QString ®ionCode )
00321 {
00322 HolidayRegion temp = HolidayRegion( regionCode );
00323 if ( temp.isValid() ) {
00324 return temp.description();
00325 } else {
00326 return QString();
00327 }
00328 }
00329
00330 bool HolidayRegion::isValid() const
00331 {
00332 return d->mHolidayFile.exists() && d->mDriver;
00333 }
00334
00335 bool HolidayRegion::isValid( const QString ®ionCode )
00336 {
00337 HolidayRegion temp = HolidayRegion( regionCode );
00338 return temp.isValid();
00339 }
00340
00341 Holiday::List HolidayRegion::holidays( const QDate &startDate, const QDate &endDate ) const
00342 {
00343 return holidays( startDate, endDate, Holiday::MultidayHolidaysAsMultipleEvents );
00344 }
00345
00346 Holiday::List HolidayRegion::holidays( const QDate &startDate, const QDate &endDate,
00347 Holiday::MultidayMode multidayMode ) const
00348 {
00349 if ( isValid() ) {
00350 return d->mDriver->parseHolidays( startDate, endDate, multidayMode );
00351 } else {
00352 return Holiday::List();
00353 }
00354 }
00355
00356 Holiday::List HolidayRegion::holidays( const QDate &date ) const
00357 {
00358 return holidays( date, Holiday::MultidayHolidaysAsMultipleEvents );
00359 }
00360
00361 Holiday::List HolidayRegion::holidays( const QDate &date, Holiday::MultidayMode multidayMode ) const
00362 {
00363 if ( isValid() ) {
00364 return d->mDriver->parseHolidays( date, multidayMode );
00365 } else {
00366 return Holiday::List();
00367 }
00368 }
00369
00370 Holiday::List HolidayRegion::holidays( int calendarYear, const QString &calendarType ) const
00371 {
00372 return holidays( calendarYear, calendarType, Holiday::MultidayHolidaysAsMultipleEvents );
00373 }
00374
00375 Holiday::List HolidayRegion::holidays( int calendarYear, const QString &calendarType,
00376 Holiday::MultidayMode multidayMode ) const
00377 {
00378 if ( isValid() ) {
00379 return d->mDriver->parseHolidays( calendarYear, calendarType, multidayMode );
00380 } else {
00381 return Holiday::List();
00382 }
00383 }
00384
00385 bool HolidayRegion::isHoliday( const QDate &date ) const
00386 {
00387 Holiday::List holidayList = holidays( date, Holiday::MultidayHolidaysAsMultipleEvents );
00388 if ( holidayList.count() > 0 ) {
00389 foreach ( const KHolidays::Holiday &holiday, holidayList ) {
00390 if ( holiday.dayType() == Holiday::NonWorkday ) {
00391 return true;
00392 }
00393 }
00394 }
00395 return false;
00396 }
00397
00398 QString HolidayRegion::defaultRegionCode( const QString &country, const QString &language )
00399 {
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 QString localeCountry, localeLanguage, localeLanguageCountry;
00410
00411 if ( country.isEmpty() ) {
00412 localeCountry = KGlobal::locale()->country().toLower();
00413 } else {
00414 localeCountry = country.toLower();
00415 }
00416
00417 if ( language.isEmpty() ) {
00418 localeLanguage = KGlobal::locale()->language().toLower();
00419 } else {
00420 localeLanguage = language.toLower();
00421 }
00422
00423 if ( localeLanguage.split('_').count() > 1 ) {
00424 localeLanguageCountry = localeLanguage.split( '_' ).at( 1 );
00425 }
00426
00427 QStringList regionList = KHolidays::HolidayRegion::regionCodes();
00428
00429 QString countryAndLanguageMatch, countryOnlyMatch, subdivisionAndLanguageMatch,
00430 subdivisionOnlyMatch, languageCountryAndLanguageMatch, languageCountryOnlyMatch,
00431 languageSubdivisionAndLanguageMatch, languageSubdivisionOnlyMatch;
00432
00433 foreach ( const QString ®ionCode, regionList ) {
00434 QString regionCountry = KHolidays::HolidayRegion::countryCode( regionCode ).toLower();
00435 QString regionSubdivisionCountry;
00436 if ( regionCountry.split( '-' ).count() > 1 ) {
00437 regionSubdivisionCountry = regionCountry.split( '-' ).at( 0 );
00438 }
00439 QString regionLanguage = KHolidays::HolidayRegion::languageCode( regionCode ).toLower();
00440
00441 if ( regionCountry == localeCountry && regionLanguage == localeLanguage ) {
00442 countryAndLanguageMatch = regionCode;
00443 break;
00444 } else if ( regionCountry == localeCountry ) {
00445 if ( countryOnlyMatch.isEmpty() ) {
00446 countryOnlyMatch = regionCode;
00447 }
00448 } else if ( !regionSubdivisionCountry.isEmpty() &&
00449 regionSubdivisionCountry == localeCountry &&
00450 regionLanguage == localeLanguage ) {
00451 if ( subdivisionAndLanguageMatch.isEmpty() ) {
00452 subdivisionAndLanguageMatch = regionCode;
00453 }
00454 } else if ( !regionSubdivisionCountry.isEmpty() && regionSubdivisionCountry == localeCountry ) {
00455 if ( subdivisionOnlyMatch.isEmpty() ) {
00456 subdivisionOnlyMatch = regionCode;
00457 }
00458 } else if ( !localeLanguageCountry.isEmpty() &&
00459 regionCountry == localeLanguageCountry &&
00460 regionLanguage == localeLanguage ) {
00461 if ( languageCountryAndLanguageMatch.isEmpty() ) {
00462 languageCountryAndLanguageMatch = regionCode;
00463 }
00464 } else if ( !localeLanguageCountry.isEmpty() && regionCountry == localeLanguageCountry ) {
00465 if ( languageCountryOnlyMatch.isEmpty() ) {
00466 languageCountryOnlyMatch = regionCode;
00467 }
00468 } else if ( !regionSubdivisionCountry.isEmpty() &&
00469 !localeLanguageCountry.isEmpty() &&
00470 regionSubdivisionCountry == localeLanguageCountry &&
00471 regionLanguage == localeLanguage ) {
00472 if ( languageSubdivisionAndLanguageMatch.isEmpty() ) {
00473 languageSubdivisionAndLanguageMatch = regionCode;
00474 }
00475 } else if ( !regionSubdivisionCountry.isEmpty() &&
00476 !localeLanguageCountry.isEmpty() &&
00477 regionSubdivisionCountry == localeLanguageCountry ) {
00478 if ( languageSubdivisionOnlyMatch.isEmpty() ) {
00479 languageSubdivisionOnlyMatch = regionCode;
00480 }
00481 }
00482 }
00483
00484 QString defaultRegionCode;
00485
00486 if ( !countryAndLanguageMatch.isEmpty() ) {
00487 defaultRegionCode = countryAndLanguageMatch;
00488 } else if ( !countryOnlyMatch.isEmpty() ) {
00489 defaultRegionCode = countryOnlyMatch;
00490 } else if ( !subdivisionAndLanguageMatch.isEmpty() ) {
00491 defaultRegionCode = subdivisionAndLanguageMatch;
00492 } else if ( !subdivisionOnlyMatch.isEmpty() ) {
00493 defaultRegionCode = subdivisionOnlyMatch;
00494 } else if ( !languageCountryAndLanguageMatch.isEmpty() ) {
00495 defaultRegionCode = languageCountryAndLanguageMatch;
00496 } else if ( !languageCountryOnlyMatch.isEmpty() ) {
00497 defaultRegionCode = languageCountryOnlyMatch;
00498 } else if ( !languageSubdivisionAndLanguageMatch.isEmpty() ) {
00499 defaultRegionCode = languageSubdivisionAndLanguageMatch;
00500 } else if ( !languageSubdivisionOnlyMatch.isEmpty() ) {
00501 defaultRegionCode = languageSubdivisionOnlyMatch;
00502 }
00503
00504 return defaultRegionCode;
00505 }