~ubuntu-branches/ubuntu/oneiric/kdepim/oneiric-updates

« back to all changes in this revision

Viewing changes to korganizer/kodaymatrix.cpp

  • Committer: Package Import Robot
  • Author(s): Philip Muškovac
  • Date: 2011-06-28 19:33:24 UTC
  • mfrom: (0.2.13) (0.1.13 sid)
  • Revision ID: package-import@ubuntu.com-20110628193324-8yvjs8sdv9rdoo6c
Tags: 4:4.7.0-0ubuntu1
* New upstream release
  - update install files
  - add missing kdepim-doc package to control file
  - Fix Vcs lines
  - kontact breaks/replaces korganizer << 4:4.6.80
  - tighten the dependency of kdepim-dev on libkdepim4 to fix lintian error

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#include "koglobals.h"
31
31
#include "koprefs.h"
32
32
 
33
 
#include <KCal/CalendarResources>
34
 
#include <KCal/DndFactory>
35
 
#include <KCal/ICalDrag>
36
 
#include <KCal/VCalDrag>
 
33
#include <calendarsupport/calendar.h>
 
34
#include <calendarsupport/utils.h>
 
35
 
 
36
#include <akonadi/itemfetchscope.h>
 
37
#include <akonadi/itemfetchjob.h>
 
38
 
 
39
#include <kcalutils/icaldrag.h>
 
40
#include <kcalutils/vcaldrag.h>
37
41
 
38
42
#include <KCalendarSystem>
39
43
#include <KIcon>
45
49
#include <QPen>
46
50
#include <QToolTip>
47
51
 
48
 
#if 0
49
 
#include "kodialogmanager.h"
50
 
 
51
 
#include <kcal/resourcecalendar.h>
52
 
 
53
 
#include <kaction.h>
54
 
#include <kstandardaction.h>
55
 
#include <kglobal.h>
56
 
#include <kdebug.h>
57
 
#include <kiconloader.h>
58
 
 
59
 
#include <QEvent>
60
 
#include <QPixmap>
61
 
#include <QApplication>
62
 
#include <QDragLeaveEvent>
63
 
#include <QPaintEvent>
64
 
#include <QDragMoveEvent>
65
 
#include <QFrame>
66
 
#include <QDropEvent>
67
 
#include <QResizeEvent>
68
 
#include <QDragEnterEvent>
69
 
#include <QCursor>
70
 
#endif
71
 
 
72
52
// ============================================================================
73
53
//  K O D A Y M A T R I X
74
54
// ============================================================================
75
55
 
 
56
using namespace KCalCore;
 
57
using namespace KCalUtils;
 
58
 
76
59
const int KODayMatrix::NOSELECTION = -1000;
77
60
const int KODayMatrix::NUMDAYS = 42;
78
61
 
93
76
  mHighlightJournals = false;
94
77
}
95
78
 
96
 
void KODayMatrix::setCalendar( Calendar *cal )
 
79
void KODayMatrix::setCalendar( CalendarSupport::Calendar *cal )
97
80
{
98
81
  if ( mCalendar ) {
99
82
    mCalendar->unregisterObserver( this );
102
85
 
103
86
  mCalendar = cal;
104
87
  mCalendar->registerObserver( this );
105
 
  CalendarResources *calres = dynamic_cast<CalendarResources*>( cal );
106
 
  if ( calres ) {
107
 
    connect( calres, SIGNAL(signalResourceAdded(ResourceCalendar *)),
108
 
             SLOT(resourcesChanged()) );
109
 
    connect( calres, SIGNAL(signalResourceModified(ResourceCalendar *)),
110
 
             SLOT(resourcesChanged()) );
111
 
    connect( calres, SIGNAL(signalResourceDeleted(ResourceCalendar *)),
112
 
             SLOT(resourcesChanged()) );
113
 
  }
114
88
 
115
89
  setAcceptDrops( mCalendar != 0 );
116
90
  updateIncidences();
216
190
 
217
191
void KODayMatrix::updateView( const QDate &actdate )
218
192
{
219
 
  if ( !actdate.isValid() ) {
 
193
  if ( !actdate.isValid() || NUMDAYS < 1 ) {
220
194
    return;
221
195
  }
222
196
  //flag to indicate if the starting day of the matrix has changed by this call
261
235
  // there's no need to update the whole list of incidences... This is just a
262
236
  // waste of computational power
263
237
  updateIncidences();
 
238
  QMap<QDate,QStringList> holidaysByDate = KOGlobals::self()->holiday( mDays[0], mDays[NUMDAYS-1] );
264
239
  for ( int i = 0; i < NUMDAYS; i++ ) {
265
240
    //if it is a holy day then draw it red. Sundays are consider holidays, too
266
 
    QStringList holidays = KOGlobals::self()->holiday( mDays[i] );
 
241
    QStringList holidays = holidaysByDate[mDays[i]];
267
242
    QString holiStr;
268
243
 
269
244
    if ( ( KOGlobals::self()->calendarSystem()->dayOfWeek( mDays[i] ) ==
270
 
           KOGlobals::self()->calendarSystem()->weekDayOfPray() ) ||
 
245
           KGlobal::locale()->weekDayOfPray() ) ||
271
246
         !holidays.isEmpty() ) {
272
247
      if ( !holidays.isEmpty() ) {
273
248
        holiStr = holidays.join( i18nc( "delimiter for joining holiday names", "," ) );
305
280
 
306
281
void KODayMatrix::updateJournals()
307
282
{
308
 
  Incidence::List incidences = mCalendar->incidences();
 
283
  const Akonadi::Item::List items = mCalendar->incidences();
309
284
 
310
 
  foreach ( Incidence *inc, incidences ) {
 
285
  foreach ( const Akonadi::Item & item, items ) {
 
286
    Incidence::Ptr inc = CalendarSupport::incidence( item );
 
287
    Q_ASSERT( inc );
311
288
    QDate d = inc->dtStart().toTimeSpec( mCalendar->timeSpec() ).date();
312
 
    if ( inc->type() == "Journal" &&
 
289
    if ( inc->type() == Incidence::TypeJournal &&
313
290
         d >= mDays[0] &&
314
291
         d <= mDays[NUMDAYS-1] &&
315
292
         !mEvents.contains( d ) ) {
316
293
      mEvents.append( d );
317
294
    }
 
295
    if ( mEvents.count() == NUMDAYS ) {
 
296
      // No point in wasting cpu, all days are bold already
 
297
      break;
 
298
    }
318
299
  }
319
300
}
320
301
 
329
310
  */
330
311
void KODayMatrix::updateTodos()
331
312
{
332
 
  Incidence::List incidences = mCalendar->incidences();
 
313
  const Akonadi::Item::List items = mCalendar->todos();
333
314
  QDate d;
334
 
  foreach ( Incidence *inc, incidences ) {
335
 
    if ( inc->type() == "Todo" ) {
336
 
      Todo *t = static_cast<Todo *>( inc );
337
 
      if ( t->hasDueDate() ) {
338
 
        ushort recurType = t->recurrenceType();
339
 
 
340
 
        if ( t->recurs() &&
341
 
             !( recurType == Recurrence::rDaily && !KOPrefs::instance()->mDailyRecur ) &&
342
 
             !( recurType == Recurrence::rWeekly && !KOPrefs::instance()->mWeeklyRecur ) )  {
343
 
 
344
 
          // It's a recurring todo, find out in which days it occurs
345
 
          DateTimeList timeDateList = t->recurrence()->timesInInterval(
346
 
                                            KDateTime( mDays[0], mCalendar->timeSpec() ),
347
 
                                            KDateTime( mDays[NUMDAYS-1], mCalendar->timeSpec() ) );
348
 
 
349
 
          foreach ( const KDateTime &dt, timeDateList ) {
350
 
            d = dt.toTimeSpec( mCalendar->timeSpec() ).date();
351
 
            if ( !mEvents.contains( d ) ) {
352
 
              mEvents.append( d );
353
 
            }
354
 
          }
355
 
 
356
 
        } else {
357
 
          d = t->dtDue().toTimeSpec( mCalendar->timeSpec() ).date();
358
 
          if ( d >= mDays[0] && d <= mDays[NUMDAYS-1] && !mEvents.contains( d ) ) {
 
315
  foreach ( const Akonadi::Item &item, items ) {
 
316
    if ( mEvents.count() == NUMDAYS ) {
 
317
      // No point in wasting cpu, all days are bold already
 
318
      break;
 
319
    }
 
320
    const Todo::Ptr t = CalendarSupport::todo( item );
 
321
    Q_ASSERT( t );
 
322
    if ( t->hasDueDate() ) {
 
323
      ushort recurType = t->recurrenceType();
 
324
 
 
325
      if ( t->recurs() &&
 
326
           !( recurType == Recurrence::rDaily && !KOPrefs::instance()->mDailyRecur ) &&
 
327
           !( recurType == Recurrence::rWeekly && !KOPrefs::instance()->mWeeklyRecur ) )  {
 
328
 
 
329
        // It's a recurring todo, find out in which days it occurs
 
330
        DateTimeList timeDateList = t->recurrence()->timesInInterval(
 
331
                                          KDateTime( mDays[0], mCalendar->timeSpec() ),
 
332
                                          KDateTime( mDays[NUMDAYS-1], mCalendar->timeSpec() ) );
 
333
 
 
334
        foreach ( const KDateTime &dt, timeDateList ) {
 
335
          d = dt.toTimeSpec( mCalendar->timeSpec() ).date();
 
336
          if ( !mEvents.contains( d ) ) {
359
337
            mEvents.append( d );
360
338
          }
361
339
        }
 
340
 
 
341
      } else {
 
342
        d = t->dtDue().toTimeSpec( mCalendar->timeSpec() ).date();
 
343
        if ( d >= mDays[0] && d <= mDays[NUMDAYS-1] && !mEvents.contains( d ) ) {
 
344
          mEvents.append( d );
 
345
        }
362
346
      }
363
347
    }
364
348
  }
366
350
 
367
351
void KODayMatrix::updateEvents()
368
352
{
369
 
  Event::List eventlist = mCalendar->events( mDays[0], mDays[NUMDAYS-1],
370
 
                                             mCalendar->timeSpec() );
371
 
 
372
 
  Event::List::ConstIterator it;
373
 
 
374
 
  for ( it=eventlist.constBegin(); it != eventlist.constEnd(); ++it ) {
375
 
    Event *event = *it;
376
 
    ushort recurType = event->recurrenceType();
377
 
 
378
 
    KDateTime dtStart = event->dtStart().toTimeSpec( mCalendar->timeSpec() );
379
 
    KDateTime dtEnd   = event->dtEnd().toTimeSpec( mCalendar->timeSpec() );
 
353
  if ( mEvents.count() == NUMDAYS ) {
 
354
    mPendingChanges = false;
 
355
    // No point in wasting cpu, all days are bold already
 
356
    return;
 
357
  }
 
358
  Akonadi::Item::List eventlist = mCalendar->events( mDays[0], mDays[NUMDAYS-1],
 
359
                                                     mCalendar->timeSpec() );
 
360
 
 
361
  Q_FOREACH ( const Akonadi::Item & item, eventlist ) {
 
362
    if ( mEvents.count() == NUMDAYS ) {
 
363
      // No point in wasting cpu, all days are bold already
 
364
      break;
 
365
    }
 
366
    const Event::Ptr event = CalendarSupport::event( item );
 
367
    Q_ASSERT( event );
 
368
    const ushort recurType = event->recurrenceType();
 
369
 
 
370
    const KDateTime dtStart = event->dtStart().toTimeSpec( mCalendar->timeSpec() );
 
371
 
 
372
    // timed incidences occur in [dtStart(), dtEnd()[. All-day incidences occur in [dtStart(), dtEnd()]
 
373
    // so we subtract 1 second in the timed case
 
374
    const int secsToAdd     = event->allDay() ? 0 : -1;
 
375
    const KDateTime dtEnd   = event->dtEnd().toTimeSpec( mCalendar->timeSpec() ).addSecs( secsToAdd );
380
376
 
381
377
    if ( !( recurType == Recurrence::rDaily  && !KOPrefs::instance()->mDailyRecur ) &&
382
378
         !( recurType == Recurrence::rWeekly && !KOPrefs::instance()->mWeeklyRecur ) ) {
383
379
 
384
380
      DateTimeList timeDateList;
385
 
      bool isRecurrent = event->recurs();
386
 
      int eventDuration = dtStart.daysTo( dtEnd );
 
381
      const bool isRecurrent = event->recurs();
 
382
      const int eventDuration = dtStart.daysTo( dtEnd );
387
383
 
388
384
      if ( isRecurrent ) {
389
385
        //Its a recurring event, find out in which days it occurs
446
442
           6 - x / mDaySize.width() : x / mDaySize.width() );
447
443
}
448
444
 
449
 
void KODayMatrix::calendarIncidenceAdded( Incidence *incidence )
450
 
{
451
 
  Q_UNUSED( incidence );
452
 
  mPendingChanges = true;
453
 
}
454
 
 
455
 
void KODayMatrix::calendarIncidenceChanged( Incidence *incidence )
456
 
{
457
 
  Q_UNUSED( incidence );
458
 
  mPendingChanges = true;
459
 
}
460
 
 
461
 
void KODayMatrix::calendarIncidenceDeleted( Incidence *incidence )
 
445
void KODayMatrix::calendarIncidenceAdded( const Akonadi::Item &incidence )
 
446
{
 
447
  Q_UNUSED( incidence );
 
448
  mPendingChanges = true;
 
449
}
 
450
 
 
451
void KODayMatrix::calendarIncidenceChanged( const Akonadi::Item &incidence )
 
452
{
 
453
  Q_UNUSED( incidence );
 
454
  mPendingChanges = true;
 
455
}
 
456
 
 
457
void KODayMatrix::calendarIncidenceDeleted( const Akonadi::Item &incidence )
462
458
{
463
459
  Q_UNUSED( incidence );
464
460
  mPendingChanges = true;
534
530
    KIcon( "task-new" ), i18n( "New &To-do..." ) );
535
531
  QAction *newJournalAction = popup.addAction(
536
532
    KIcon( "journal-new" ), i18n( "New &Journal..." ) );
537
 
 
538
533
  QAction *ret = popup.exec( QCursor::pos() );
539
534
  if ( ret == newEventAction ) {
540
535
    emit newEventSignal( date );
560
555
    mSelEnd = mSelInit;
561
556
    if ( tmp != mSelStart ) {
562
557
      mSelStart = tmp;
563
 
      repaint();
 
558
      update();
564
559
    }
565
560
  } else {
566
561
    mSelStart = mSelInit;
568
563
    //repaint only if selection has changed
569
564
    if ( tmp != mSelEnd ) {
570
565
      mSelEnd = tmp;
571
 
      repaint();
 
566
      update();
572
567
    }
573
568
  }
574
569
 
579
574
  for ( int i = mSelStart; i <= mSelEnd; ++i ) {
580
575
    daylist.append( mDays[i] );
581
576
  }
582
 
  emit selected( ( const DateList )daylist );
 
577
  emit selected( static_cast<const DateList>(daylist) );
583
578
}
584
579
 
585
580
void KODayMatrix::mouseMoveEvent( QMouseEvent *e )
593
588
    mSelEnd = mSelInit;
594
589
    if ( tmp != mSelStart ) {
595
590
      mSelStart = tmp;
596
 
      repaint();
 
591
      update();
597
592
    }
598
593
  } else {
599
594
    mSelStart = mSelInit;
601
596
    //repaint only if selection has changed
602
597
    if ( tmp != mSelEnd ) {
603
598
      mSelEnd = tmp;
604
 
      repaint();
 
599
      update();
605
600
    }
606
601
  }
607
602
}
624
619
{
625
620
  e->acceptProposedAction();
626
621
  const QMimeData *md = e->mimeData();
627
 
  if ( !ICalDrag::canDecode( md ) && !VCalDrag::canDecode( md ) ) {
 
622
  if ( !CalendarSupport::canDecode( md )) {
628
623
    e->ignore();
629
624
    return;
630
625
  }
640
635
void KODayMatrix::dragMoveEvent( QDragMoveEvent *e )
641
636
{
642
637
  const QMimeData *md = e->mimeData();
643
 
  if ( !ICalDrag::canDecode( md ) && !VCalDrag::canDecode( md ) ) {
 
638
  if ( !CalendarSupport::canDecode( md ) ) {
644
639
    e->ignore();
645
640
    return;
646
641
  }
664
659
    e->ignore();
665
660
    return;
666
661
  }
667
 
 
668
 
  DndFactory factory( mCalendar );
669
 
  Event *event = factory.createDropEvent( e );
670
 
  Todo *todo = factory.createDropTodo( e );
671
 
  if ( !event && !todo ) {
 
662
  QList<QUrl> urls = ( e->mimeData()->urls() );
 
663
  //kDebug()<<" urls :"<<urls;
 
664
  if ( urls.isEmpty() ) {
672
665
    e->ignore();
673
666
    return;
674
667
  }
675
 
 
676
 
  Todo *existingTodo = 0;
677
 
  Event *existingEvent = 0;
678
 
 
679
 
  // Find the incidence in the calendar, then we don't need the drag object any more
680
 
  if ( event ) {
681
 
    existingEvent = mCalendar->event( event->uid() );
682
 
  }
683
 
  if ( todo ) {
684
 
    existingTodo = mCalendar->todo( todo->uid() );
685
 
  }
686
 
 
687
 
  int action = DRAG_CANCEL;
688
 
 
689
 
  Qt::KeyboardModifiers keyboardModifiers = e->keyboardModifiers();
690
 
 
691
 
  if ( keyboardModifiers & Qt::ControlModifier ) {
692
 
    action = DRAG_COPY;
693
 
  } else if ( keyboardModifiers & Qt::ShiftModifier ) {
694
 
    action = DRAG_MOVE;
695
 
  } else {
696
 
    QAction *copy = 0, *move = 0, *cancel = 0;
697
 
    KMenu *menu = new KMenu( this );
698
 
    if ( existingEvent || existingTodo ) {
699
 
      move = menu->addAction( KOGlobals::self()->smallIcon( "edit-paste" ), i18n( "&Move" ) );
700
 
      if ( existingEvent ) {
701
 
        copy = menu->addAction( KOGlobals::self()->smallIcon( "edit-copy" ), i18n( "&Copy" ) );
702
 
      }
703
 
    } else {
704
 
      move = menu->addAction( KOGlobals::self()->smallIcon( "list-add" ), i18n( "&Add" ) );
 
668
  Akonadi::Item items;
 
669
  //For the moment support 1 url
 
670
  if ( urls.count() >= 1 ) {
 
671
    KUrl res = urls.at( 0 );
 
672
 
 
673
    Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( Akonadi::Item::fromUrl( res ) );
 
674
    job->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
 
675
    job->fetchScope().fetchFullPayload();
 
676
    Akonadi::Item::List items;
 
677
    if ( job->exec() ) {
 
678
      items = job->items();
705
679
    }
706
 
    menu->addSeparator();
707
 
    cancel = menu->addAction( KOGlobals::self()->smallIcon( "process-stop" ), i18n( "&Cancel" ) );
708
 
    QAction *a = menu->exec( QCursor::pos() );
709
 
    if ( a == copy ) {
 
680
    bool exist = items.at( 0 ).isValid();
 
681
    int action = DRAG_CANCEL;
 
682
 
 
683
    Qt::KeyboardModifiers keyboardModifiers = e->keyboardModifiers();
 
684
 
 
685
    if ( keyboardModifiers & Qt::ControlModifier ) {
710
686
      action = DRAG_COPY;
711
 
    } else if ( a == move ) {
 
687
    } else if ( keyboardModifiers & Qt::ShiftModifier ) {
712
688
      action = DRAG_MOVE;
713
 
    }
714
 
  }
715
 
 
716
 
  if ( action == DRAG_COPY  || action == DRAG_MOVE ) {
717
 
    e->accept();
718
 
    int idx = getDayIndexFrom( e->pos().x(), e->pos().y() );
719
 
 
720
 
    if ( action == DRAG_COPY ) {
721
 
      if ( event ) {
722
 
        emit incidenceDropped( event, mDays[idx] );
723
 
      }
724
 
      if ( todo ) {
725
 
        emit incidenceDropped( todo, mDays[idx] );
726
 
      }
727
 
    } else if ( action == DRAG_MOVE ) {
728
 
      if ( event ) {
729
 
        emit incidenceDroppedMove( event, mDays[idx] );
730
 
      }
731
 
      if ( todo ) {
732
 
        emit incidenceDroppedMove( todo, mDays[idx] );
733
 
      }
734
 
    }
735
 
  }
736
 
  delete event;
737
 
  delete todo;
 
689
    } else {
 
690
      QAction *copy = 0, *move = 0, *cancel = 0;
 
691
      KMenu *menu = new KMenu( this );
 
692
      if ( exist ) {
 
693
        move = menu->addAction( KOGlobals::self()->smallIcon( "edit-paste" ), i18n( "&Move" ) );
 
694
        if ( /*existingEvent*/1 ) {
 
695
          copy = menu->addAction( KOGlobals::self()->smallIcon( "edit-copy" ), i18n( "&Copy" ) );
 
696
        }
 
697
      } else {
 
698
        move = menu->addAction( KOGlobals::self()->smallIcon( "list-add" ), i18n( "&Add" ) );
 
699
      }
 
700
      menu->addSeparator();
 
701
      cancel = menu->addAction( KOGlobals::self()->smallIcon( "process-stop" ), i18n( "&Cancel" ) );
 
702
      QAction *a = menu->exec( QCursor::pos() );
 
703
      if ( a == copy ) {
 
704
        action = DRAG_COPY;
 
705
      } else if ( a == move ) {
 
706
        action = DRAG_MOVE;
 
707
      }
 
708
    }
 
709
 
 
710
    if ( action == DRAG_COPY  || action == DRAG_MOVE ) {
 
711
      e->accept();
 
712
      int idx = getDayIndexFrom( e->pos().x(), e->pos().y() );
 
713
 
 
714
      if ( action == DRAG_COPY ) {
 
715
          emit incidenceDropped( items.at( 0 ), mDays[idx] );
 
716
      } else if ( action == DRAG_MOVE ) {
 
717
          emit incidenceDroppedMove( items.at( 0 ), mDays[idx] );
 
718
      }
 
719
    }
 
720
  }
738
721
}
739
722
#endif
740
723
 
811
794
  QColor actcol = textColorShaded;
812
795
  p.setPen( actcol );
813
796
  QPen tmppen;
814
 
  for ( int i=0; i<NUMDAYS; ++i ) {
 
797
 
 
798
  const QList<QDate> workDays = KOGlobals::self()->workDays( mDays[0], mDays[NUMDAYS-1] );
 
799
  for ( int i = 0; i < NUMDAYS; ++i ) {
815
800
    row = i / 7;
816
801
    col = isRTL ? 6 - ( i - row * 7 ) : i - row * 7;
817
802
 
830
815
      p.setPen( actcol );
831
816
    }
832
817
 
833
 
    bool holiday = ! KOGlobals::self()->isWorkDay( mDays[i] );
 
818
    const bool holiday = !workDays.contains( mDays[i] );
 
819
 
834
820
    QColor holidayColorShaded =
835
821
      getShadedColor( KOPrefs::instance()->agendaHolidaysBackgroundColor() );
836
822
 
875
861
    }
876
862
 
877
863
    // draw selected days with special color
878
 
    // DO NOT specially highlight holidays in selection !
879
 
    if ( i >= mSelStart && i <= mSelEnd ) {
880
 
      p.setPen( QColor( "white" ) );
 
864
    if ( i >= mSelStart && i <= mSelEnd && !holiday ) {
 
865
      p.setPen( Qt::white );
881
866
    }
882
867
 
883
868
    p.drawText( col * dwidth, row * dheight, dwidth, dheight,
908
893
  mDaySize.setWidth( sz.width() / 7 );
909
894
}
910
895
 
 
896
/* static */
 
897
QPair<QDate,QDate> KODayMatrix::matrixLimits( const QDate &month )
 
898
{
 
899
  const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
 
900
  QDate d = month;
 
901
  calSys->setYMD( d, calSys->year( month ), calSys->month( month ), 1 );
 
902
 
 
903
  const int dayOfWeek = calSys->dayOfWeek( d );
 
904
  const int weekstart = KGlobal::locale()->weekStartDay();
 
905
 
 
906
  d = d.addDays( -( 7 + dayOfWeek - weekstart ) % 7 );
 
907
 
 
908
  if ( dayOfWeek == weekstart ) {
 
909
    d = d.addDays( -7 ); // Start on the second line
 
910
  }
 
911
 
 
912
  return qMakePair( d, d.addDays( NUMDAYS-1 ) );
 
913
}
 
914
 
 
915
 
911
916
#include "kodaymatrix.moc"