korganizer Library API Documentation

kdatenavigator.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 2001,2002,2003 Cornelius Schumacher <schumacher@kde.org>
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 
00020     As a special exception, permission is given to link this program
00021     with any edition of Qt, and distribute the resulting executable,
00022     without including the source code for Qt in the source distribution.
00023 */
00024 
00025 #include <qstring.h>
00026 #include <qkeycode.h>
00027 #include <qlayout.h>
00028 #include <qtimer.h>
00029 #include <qframe.h>
00030 #include <qlabel.h>
00031 
00032 #include <kdebug.h>
00033 #include <klocale.h>
00034 #include <kglobal.h>
00035 #include <kglobalsettings.h>
00036 
00037 #include "koglobals.h"
00038 #include "koprefs.h"
00039 #ifndef KORG_NOPLUGINS
00040 #include "kocore.h"
00041 #endif
00042 
00043 #include <kcalendarsystem.h>
00044 
00045 #include "navigatorbar.h"
00046 
00047 #include "kdatenavigator.h"
00048 
00049 KDateNavigator::KDateNavigator( QWidget *parent,
00050                                 bool show_week_nums, const char *name,
00051                                 QDate startDate )
00052   : QFrame( parent, name ),
00053     updateTimer( 0 )
00054 {
00055   setFrameStyle( QFrame::NoFrame );
00056 
00057   QGridLayout *topLayout = new QGridLayout( this, 8, 8 );
00058 
00059   if ( !startDate.isValid() ) {
00060     kdDebug(5850) << "KDateNavigator::KDateNavigator(): an invalid date was passed as a parameter!" << endl;
00061     startDate = QDate::currentDate();
00062   }
00063 
00064   mSelectedDates.append( startDate );
00065   m_MthYr = startDate;
00066   m_bShowWeekNums = show_week_nums;
00067 
00068   mNavigatorBar = new NavigatorBar( startDate, this );
00069   topLayout->addMultiCellWidget( mNavigatorBar, 0, 0, 0, 7 );
00070 
00071   connect( mNavigatorBar, SIGNAL( goPrevYear() ), SIGNAL( goPrevYear() ) );
00072   connect( mNavigatorBar, SIGNAL( goPrevMonth() ), SIGNAL( goPrevMonth() ) );
00073   connect( mNavigatorBar, SIGNAL( goNextMonth() ), SIGNAL( goNextMonth() ) );
00074   connect( mNavigatorBar, SIGNAL( goNextYear() ), SIGNAL( goNextYear() ) );
00075   connect( mNavigatorBar, SIGNAL( goMonth( int ) ), SIGNAL( goMonth( int ) ) );
00076 
00077   // get the day of the week on the first day
00078   QDate dayone( m_MthYr.year(), m_MthYr.month(), 1 );
00079   m_fstDayOfWk = dayone.dayOfWeek();
00080 
00081   int i;
00082   QString generalFont = KGlobalSettings::generalFont().family();
00083 
00084   // Set up the heading fields.
00085   for( i = 0; i < 7; i++ ) {
00086     headings[i] = new QLabel(this);
00087     headings[i]->setFont(QFont(generalFont, 10, QFont::Bold));
00088     headings[i]->setAlignment(AlignCenter);
00089 
00090     topLayout->addWidget(headings[i],1,i+1);
00091   }
00092 
00093   // Create the weeknumber labels
00094   for( i = 0; i < 6; i++ ) {
00095     weeknos[i] = new QLabel(this);
00096     weeknos[i]->setAlignment(AlignCenter);
00097     weeknos[i]->setFont(QFont(generalFont, 10));
00098     if(!show_week_nums) {
00099       weeknos[i]->hide();
00100     }
00101     weeknos[i]->installEventFilter(this);
00102 
00103     topLayout->addWidget(weeknos[i],i+2,0);
00104   }
00105 
00106   mDayMatrix = new KODayMatrix( this, dayone, "KDateNavigator::dayMatrix");
00107   mDayMatrix->setFrameStyle(QFrame::Panel|QFrame::Sunken);
00108   mDayMatrix->setLineWidth(1);
00109 
00110   connect( mDayMatrix, SIGNAL( selected( const KCal::DateList & ) ),
00111            SIGNAL( datesSelected( const KCal::DateList & ) ) );
00112 
00113   connect( mDayMatrix, SIGNAL( eventDropped( Event * ) ),
00114            SIGNAL( eventDropped( Event * ) ) );
00115   connect( mDayMatrix, SIGNAL( eventDroppedMove( Event * , Event * ) ),
00116            SIGNAL( eventDroppedMove( Event *, Event * ) ) );
00117   connect( mDayMatrix, SIGNAL( todoDropped( Todo * ) ),
00118            SIGNAL( todoDropped( Todo * ) ) );
00119   connect( mDayMatrix, SIGNAL( todoDroppedMove( Todo * , Todo * ) ),
00120            SIGNAL( todoDroppedMove( Todo *, Todo * ) ) );
00121 
00122   topLayout->addMultiCellWidget( mDayMatrix, 2, 7, 1, 7 );
00123 
00124   // read settings from configuration file.
00125   updateConfig();
00126   enableRollover( FollowMonth );
00127 }
00128 
00129 void KDateNavigator::enableRollover( RolloverType r )
00130 {
00131   switch( r ) {
00132     case None:
00133       if ( updateTimer ) {
00134         updateTimer->stop();
00135         delete updateTimer;
00136         updateTimer = 0;
00137       }
00138       break;
00139     case FollowDay:
00140     case FollowMonth:
00141       if ( !updateTimer ) {
00142         updateTimer = new QTimer( this );
00143         connect( updateTimer, SIGNAL( timeout() ),
00144                  SLOT( possiblyPastMidnight() ) );
00145       }
00146       updateTimer->start( 0, true );
00147       lastDayChecked = QDate::currentDate();
00148   }
00149   updateRollover = r;
00150 }
00151 
00152 KDateNavigator::~KDateNavigator()
00153 {
00154 }
00155 
00156 void KDateNavigator::setCalendar( Calendar *cal )
00157 {
00158   mDayMatrix->setCalendar( cal );
00159 }
00160 
00161 void KDateNavigator::passedMidnight()
00162 {
00163   QDate today = QDate::currentDate();
00164   bool emitMonth = false;
00165 
00166   if ( today.month() != lastDayChecked.month() ) {
00167      if ( updateRollover == FollowMonth &&
00168          mDayMatrix->isEndOfMonth() ) {
00169        goNextMonth();
00170        emitMonth = true;
00171      }
00172   }
00173   mDayMatrix->recalculateToday();
00174   mDayMatrix->repaint();
00175   emit dayPassed( today );
00176   if ( emitMonth ) {
00177     emit monthPassed( today );
00178   }
00179 }
00180 
00181 void KDateNavigator::possiblyPastMidnight()
00182 {
00183   if ( lastDayChecked != QDate::currentDate() ) {
00184     passedMidnight();
00185     lastDayChecked = QDate::currentDate();
00186   }
00187   // Set the timer to go off 1 second after midnight
00188   // or after 8 minutes, whichever comes first.
00189   if ( updateTimer ) {
00190     QTime now = QTime::currentTime();
00191     QTime midnight = QTime( 23, 59, 59 );
00192     int msecsWait = QMIN( 480000, now.msecsTo( midnight ) + 2000 );
00193 
00194     // qDebug(QString("Waiting %1 msec from %2 to %3.").arg(msecsWait)
00195     //        .arg(now.toString()).arg(midnight.toString()));
00196 
00197     updateTimer->stop();
00198     updateTimer->start( msecsWait, true );
00199   }
00200 }
00201 
00202 void KDateNavigator::updateDates()
00203 {
00204   // Find the first day of the week of the current month.
00205   //int d1 = KOGlobals::self()->calendarSystem()->day( m_MthYr );
00206   QDate dayone( m_MthYr.year(), m_MthYr.month(), m_MthYr.day() );
00207   int d2 = KOGlobals::self()->calendarSystem()->day( dayone );
00208   //int di = d1 - d2 + 1;
00209   dayone = dayone.addDays( -d2 + 1 );
00210 
00211   int m_fstDayOfWkCalsys = KOGlobals::self()->calendarSystem()->dayOfWeek( dayone );
00212 
00213   // If month begins on Monday and Monday is first day of week,
00214   // month should begin on second line. Sunday doesn't have this problem.
00215   int nextLine = ( ( m_fstDayOfWkCalsys == 1) &&
00216                    ( KGlobal::locale()->weekStartDay() == 1 ) ) ? 7 : 0;
00217 
00218   // update the matrix dates
00219   int index = (KGlobal::locale()->weekStartDay() == 1 ? 1 : 0) - m_fstDayOfWkCalsys - nextLine;
00220 
00221 
00222   mDayMatrix->updateView(dayone.addDays(index));
00223 //each updateDates is followed by an updateView -> repaint is issued there !
00224 //  mDayMatrix->repaint();
00225 }
00226 
00227 void KDateNavigator::updateDayMatrix()
00228 {
00229   mDayMatrix->updateView();
00230   mDayMatrix->repaint();
00231 }
00232 
00233 
00234 void KDateNavigator::updateView()
00235 {
00236   setUpdatesEnabled( false );
00237 
00238   int i;
00239 
00240 //  kdDebug(5850) << "updateView() -> mDayMatrix->updateView()" << endl;
00241   mDayMatrix->updateView();
00242 
00243   // set the week numbers.
00244   for(i = 0; i < 6; i++) {
00245     QString weeknum;
00246     // remember, according to ISO 8601, the first week of the year is the
00247     // first week that contains a thursday.  Thus we must subtract off 4,
00248     // not just 1.
00249 
00250     //ET int dayOfYear = buttons[(i + 1) * 7 - 4]->date().dayOfYear();
00251     int dayOfYear = KOGlobals::self()->calendarSystem()->dayOfYear((mDayMatrix->getDate((i+1)*7-4)));
00252 
00253     if (dayOfYear % 7 != 0)
00254       weeknum.setNum(dayOfYear / 7 + 1);
00255     else
00256       weeknum.setNum(dayOfYear / 7);
00257     weeknos[i]->setText(weeknum);
00258   }
00259 
00260   setUpdatesEnabled( true );
00261 //  kdDebug(5850) << "updateView() -> repaint()" << endl;
00262   repaint();
00263   mDayMatrix->repaint();
00264 }
00265 
00266 void KDateNavigator::updateConfig()
00267 {
00268   int day;
00269   for(int i=0; i<7; i++) {
00270     // take the first letter of the day name to be the abbreviation
00271     if ( KGlobal::locale()->weekStartDay() == 1 ) {
00272       day = i+1;
00273     } else {
00274       if (i==0) day = 7;
00275       else day = i;
00276     }
00277     QString dayName = KOGlobals::self()->calendarSystem()->weekDayName( day,
00278                                                                         true );
00279     if ( KOPrefs::instance()->mCompactDialogs ) dayName = dayName.left( 1 );
00280     headings[i]->setText( dayName );
00281   }
00282   updateDates();
00283   updateView();
00284 }
00285 
00286 void KDateNavigator::setShowWeekNums(bool enabled)
00287 {
00288   m_bShowWeekNums = enabled;
00289   for(int i=0; i<6; i++) {
00290     if(enabled)
00291       weeknos[i]->show();
00292     else
00293       weeknos[i]->hide();
00294   }
00295   resize(size());
00296 }
00297 
00298 void KDateNavigator::selectDates( const DateList &dateList )
00299 {
00300   if ( dateList.count() > 0 ) {
00301     mNavigatorBar->selectDates( dateList );
00302 
00303     mSelectedDates = dateList;
00304 
00305     // set our record of the month and year that this datetbl is
00306     // displaying.
00307     m_MthYr = mSelectedDates.first();
00308 
00309 
00310     // set our record of the first day of the week of the current
00311     // month. This needs to be done before calling dayToIndex, since it
00312     // relies on this information being up to date.
00313     QDate dayone( m_MthYr.year(), m_MthYr.month(), 1 );
00314     m_fstDayOfWk = dayone.dayOfWeek();
00315 
00316     updateDates();
00317 
00318     mDayMatrix->setSelectedDaysFrom( *( dateList.begin() ),
00319                                      *( --dateList.end() ) );
00320 
00321     updateView();
00322   }
00323 }
00324 
00325 int KDateNavigator::dayNum( int row, int col )
00326 {
00327   return 7 * ( row - 1 ) + ( col + 1 ) - m_fstDayOfWk;
00328 }
00329 
00330 int KDateNavigator::dayToIndex( int dayNum )
00331 {
00332   int row, col;
00333 
00334   row = ( dayNum + m_fstDayOfWk - 1 -
00335           ( KGlobal::locale()->weekStartDay() == 1 ? 1 : 0 ) ) / 7;
00336   if ( KGlobal::locale()->weekStartDay() == 1 && ( m_fstDayOfWk == 1 ) )
00337     row++;
00338   col = ( dayNum + m_fstDayOfWk - 1 -
00339           ( KGlobal::locale()->weekStartDay() == 1 ? 1 : 0 ) ) % 7;
00340   return row * 7 + col;
00341 }
00342 
00343 void KDateNavigator::wheelEvent ( QWheelEvent *e )
00344 {
00345   if( e->delta() > 0 ) emit goPrevious();
00346   else emit goNext();
00347 
00348   e->accept();
00349 }
00350 
00351 bool KDateNavigator::eventFilter ( QObject *o, QEvent *e )
00352 {
00353   if ( e->type() == QEvent::MouseButtonPress ) {
00354     int i;
00355     for( i = 0; i < 6; ++i ) {
00356       if ( o == weeknos[ i ] ) {
00357         QDate weekstart = mDayMatrix->getDate( i * 7 );
00358         emit weekClicked( weekstart );
00359         break;
00360       }
00361     }
00362     return true;
00363   } else {
00364     return false;
00365   }
00366 }
00367 
00368 #include "kdatenavigator.moc"
KDE Logo
This file is part of the documentation for korganizer Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat May 1 11:38:27 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003