Bug 92474

Summary: holiday plugin: when two holiday items are on same date, only one is displayed
Product: [Applications] korganizer Reporter: Wilbert Berendsen <wbsoft>
Component: generalAssignee: Reinhold Kainhofer <reinhold>
Status: RESOLVED FIXED    
Severity: normal    
Priority: NOR    
Version: 3.3.1   
Target Milestone: ---   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Wilbert Berendsen 2004-10-31 19:09:49 UTC
Version:           3.3.1 (using KDE 3.3.1, compiled sources)
Compiler:          gcc version 3.3.4
OS:                Linux (i686) release 2.6.7

This is not a severe bug, but sometimes an item like 'Wintertijd' coincides with 'Allerheiligen', etc.

Only one of them is then shown in Korganizer.

It would be nicer is both are shown (e.g. on two lines, it occurs so seldomly)
Comment 1 Reinhold Kainhofer 2006-06-09 18:02:51 UTC
SVN commit 549721 by kainhofe:

The holiday library now also supports 
-) Multiple holidays on the same date (e.g. start of summer time and easter 
   on the same day, etc.)
-) conditional shifting of holidays (e.g. if a holiday occurs on a saturday 
   or sunday, it is actually celebrated on the following monday). Example: 
      small  "May holiday" weekend on 1.5. shift to monday if saturday || sunday
   The holiday data files still need to be adapted wherever such a system 
   applies (UK, Wales, Ireland are known from bug reports, but I don't 
   know which holidays are really affected).

It's incredible, how simple it is to hack these lex/yacc parsers (which had the fame that nobody in kde would understand them), once you take the ten minutes to print out a yacc tutorial and the 45 minutes to look at the code (and then the ~2 hours to fix the inadvertant bugs in the C code that come through the ancient pointer-increasing in C to walk through a list, when you are used to Qt-style list iterators  ;-) )

CCBUG:64673
CCBUG:92474


 M  +1 -1      Makefile.am  
 M  +33 -11    kholidays.cpp  
 M  +12 -4     kholidays.h  
 M  +162 -106  parseholiday.y  
 M  +3 -0      scanholiday.lex  
Comment 2 Reinhold Kainhofer 2006-06-09 18:42:14 UTC
SVN commit 549733 by kainhofe:

Implement support for the new features in libkholiday:
-) Multiple holidays are possible on a day (e.g. start of summer time and easter)

BUG:92474



 M  +5 -4      kontact/plugins/specialdates/sdsummarywidget.cpp  
 M  +7 -2      korganizer/actionmanager.cpp  
 M  +8 -9      korganizer/koagendaview.cpp  
 M  +1 -1      korganizer/kocorehelper.cpp  
 M  +13 -9     korganizer/kodaymatrix.cpp  
 M  +18 -9     korganizer/koglobals.cpp  
 M  +1 -1      korganizer/koglobals.h  
 M  +2 -2      korganizer/komonthview.cpp  
 M  +5 -1      libkcal/htmlexport.cpp  


--- branches/KDE/3.5/kdepim/kontact/plugins/specialdates/sdsummarywidget.cpp #549732:549733
@@ -359,13 +359,14 @@
       for ( dt=QDate::currentDate();
             dt<=QDate::currentDate().addDays( mDaysAhead - 1 );
             dt=dt.addDays(1) ) {
-        QString holstring = mHolidays->shortText( dt );
-        if ( !holstring.isNull() && !holstring.isEmpty() ) {
+        QValueList<KHoliday> holidays = mHolidays->getHolidays( dt );
+        QValueList<KHoliday>::ConstIterator it = holidays.begin();
+        for ( ; it != holidays.end(); ++it ) {
           SDEntry entry;
           entry.type = IncidenceTypeEvent;
-          entry.category = CategoryHoliday;
+          entry.category = ((*it).Category==KHolidays::HOLIDAY)?CategoryHoliday:CategoryOther;
           entry.date = dt;
-          entry.summary = holstring;
+          entry.summary = (*it).text;
           dateDiff( dt, entry.daysTo, entry.yearsOld );
           entry.yearsOld = -1; //ignore age of holidays
           entry.span = 1;
--- branches/KDE/3.5/kdepim/korganizer/actionmanager.cpp #549732:549733
@@ -1039,8 +1039,13 @@
   QDate cdate = settings->dateStart().date();
   QDate qd2 = settings->dateEnd().date();
   while ( cdate <= qd2 ) {
-    if ( !KOGlobals::self()->holiday( cdate ).isEmpty() )
-      mExport.addHoliday( cdate, KOGlobals::self()->holiday( cdate ) );
+    QStringList holidays = KOGlobals::self()->holiday( cdate );
+    if ( !holidays.isEmpty() ) {
+      QStringList::ConstIterator it = holidays.begin();
+      for ( ; it != holidays.end(); ++it ) {
+        mExport.addHoliday( cdate, *it );
+      }
+    }
     cdate = cdate.addDays( 1 );
   }
 
--- branches/KDE/3.5/kdepim/korganizer/koagendaview.cpp #549732:549733
@@ -775,15 +775,14 @@
     dayLayout->addWidget(dayLabel);
 
     // if a holiday region is selected, show the holiday name
-    if ( KOGlobals::self()->holidays() ) {
-      QString text = KOGlobals::self()->holidays()->shortText( date );
-      if ( !text.isEmpty() ) {
-        // use a KOAlternateLabel so when the text doesn't fit any more a tooltip is used
-        KOAlternateLabel*label = new KOAlternateLabel( text, text, QString::null, mDayLabels );
-        label->setMinimumWidth(1);
-        label->setAlignment(AlignCenter);
-        dayLayout->addWidget(label);
-      }
+    QStringList texts = KOGlobals::self()->holiday( date );
+    QStringList::ConstIterator textit = texts.begin();
+    for ( ; textit != texts.end(); ++textit ) {
+      // use a KOAlternateLabel so when the text doesn't fit any more a tooltip is used
+      KOAlternateLabel*label = new KOAlternateLabel( (*textit), (*textit), QString::null, mDayLabels );
+      label->setMinimumWidth(1);
+      label->setAlignment(AlignCenter);
+      dayLayout->addWidget(label);
     }
 
 #ifndef KORG_NOPLUGINS
--- branches/KDE/3.5/kdepim/korganizer/kocorehelper.cpp #549732:549733
@@ -40,5 +40,5 @@
 
 QString KOCoreHelper::holidayString( const QDate &dt )
 {
-  return KOGlobals::self()->holiday( dt );
+  return KOGlobals::self()->holiday( dt ).join( i18n("delimiter for joining holiday names", ", " ) );
 }
--- branches/KDE/3.5/kdepim/korganizer/kodaymatrix.cpp #549732:549733
@@ -99,7 +99,7 @@
 const int KODayMatrix::NUMDAYS = 42;
 
 KODayMatrix::KODayMatrix( QWidget *parent, const char *name )
-  : QFrame( parent, name ), mCalendar( 0 ), mStartDate( 1970, 1, 1 )
+  : QFrame( parent, name ), mCalendar( 0 ), mStartDate()
 {
   // initialize dynamic arrays
   mDays = new QDate[ NUMDAYS ];
@@ -179,8 +179,10 @@
 
 void KODayMatrix::setSelectedDaysFrom( const QDate &start, const QDate &end )
 {
-  mSelStart = mStartDate.daysTo( start );
-  mSelEnd = mStartDate.daysTo( end );
+  if ( mStartDate.isValid() ) {
+    mSelStart = mStartDate.daysTo( start );
+    mSelEnd = mStartDate.daysTo( end );
+  }
 }
 
 void KODayMatrix::clearSelection()
@@ -190,6 +192,7 @@
 
 void KODayMatrix::recalculateToday()
 {
+  if ( !mStartDate.isValid() ) return;
   mToday = -1;
   for ( int i = 0; i < NUMDAYS; i++ ) {
     mDays[ i ] = mStartDate.addDays( i );
@@ -212,7 +215,8 @@
 
 void KODayMatrix::updateView( const QDate &actdate )
 {
-//  kdDebug(5850) << "KODayMatrix::updateView() " << actdate.toString() << endl;
+ kdDebug(5850) << "KODayMatrix::updateView() " << actdate << ", day start="<<mStartDate<< endl;
+ if ( !actdate.isValid() ) return;
 
   //flag to indicate if the starting day of the matrix has changed by this call
   bool daychanged = false;
@@ -250,16 +254,16 @@
   updateEvents();
   for( int i = 0; i < NUMDAYS; i++ ) {
     //if it is a holy day then draw it red. Sundays are consider holidays, too
-    QString holiStr = KOGlobals::self()->holiday( mDays[ i ] );
+    QStringList holidays = KOGlobals::self()->holiday( mDays[ i ] );
+    QString holiStr = QString::null;
 
     if ( ( KOGlobals::self()->calendarSystem()->dayOfWeek( mDays[ i ] ) ==
            KOGlobals::self()->calendarSystem()->weekDayOfPray() ) ||
-         !holiStr.isEmpty() ) {
+         !holidays.isEmpty() ) {
+      if ( !holidays.isEmpty() ) holiStr = holidays.join( i18n("delimiter for joining holiday names", ", " ) );
       if ( holiStr.isNull() ) holiStr = "";
-      mHolidays[ i ] = holiStr;
-    } else {
-      mHolidays[ i ] = QString::null;
     }
+    mHolidays[ i ] = holiStr;
   }
 }
 
--- branches/KDE/3.5/kdepim/korganizer/koglobals.cpp #549732:549733
@@ -141,10 +141,17 @@
   return SmallIconSet( name, size, mOwnInstance );
 }
 
-QString KOGlobals::holiday( const QDate &date )
+QStringList KOGlobals::holiday( const QDate &date )
 {
-  if ( mHolidays ) return mHolidays->shortText( date );
-  else return QString::null;
+  QStringList hdays;
+
+  if ( !mHolidays ) return hdays;
+  QValueList<KHoliday> list = mHolidays->getHolidays( date );
+  QValueList<KHoliday>::ConstIterator it = list.begin();
+  for ( ; it != list.end(); ++it ) {
+    hdays.append( (*it).text );
+  }
+  return hdays;
 }
 
 bool KOGlobals::isWorkDay( const QDate &date )
@@ -152,12 +159,14 @@
   int mask( ~( KOPrefs::instance()->mWorkWeekMask ) );
 
   bool nonWorkDay = ( mask & ( 1 << ( date.dayOfWeek() - 1 ) ) );
-
-  nonWorkDay = nonWorkDay
-               || ( KOPrefs::instance()->mExcludeHolidays
-                    && ( mHolidays
-                         && ( mHolidays->category( date ) == KHolidays::HOLIDAY ) ) );
-
+  if ( KOPrefs::instance()->mExcludeHolidays && mHolidays ) {
+    QValueList<KHoliday> list = mHolidays->getHolidays( date );
+    QValueList<KHoliday>::ConstIterator it = list.begin();
+    for ( ; it != list.end(); ++it ) {
+      nonWorkDay = nonWorkDay
+               || ( (*it).Category == KHolidays::HOLIDAY );
+    }
+  }
   return !nonWorkDay;
 }
 
--- branches/KDE/3.5/kdepim/korganizer/koglobals.h #549732:549733
@@ -59,7 +59,7 @@
     QPixmap smallIcon( const QString& name );
     QIconSet smallIconSet( const QString& name, int size = 0 );
 
-    QString holiday( const QDate & );
+    QStringList holiday( const QDate & );
     bool isWorkDay( const QDate & );
 
     /**
--- branches/KDE/3.5/kdepim/korganizer/komonthview.cpp #549732:549733
@@ -896,8 +896,8 @@
     mCells[i]->setHoliday( isHoliday );
 
     // add holiday, if present
-    QString hstring( KOGlobals::self()->holiday( date ) );
-    mCells[i]->setHolidayString( hstring );
+    QStringList holidays( KOGlobals::self()->holiday( date ) );
+    mCells[i]->setHolidayString( holidays.join( i18n("delimiter for joining holiday names", ", " ) ) );
   }
 
   updateView();
--- branches/KDE/3.5/kdepim/libkcal/htmlexport.cpp #549732:549733
@@ -695,7 +695,11 @@
 
 void HtmlExport::addHoliday( const QDate &date, const QString &name)
 {
-  mHolidayMap[date] = name;
+  if ( mHolidayMap[date].isEmpty() ) {
+    mHolidayMap[date] = name;
+  } else {
+    mHolidayMap[date] = i18n("list of holidays", "%1, %2").arg(mHolidayMap[date]).arg(name);
+  }
 }
 
 QDate HtmlExport::fromDate() const