korganizer

datenavigator.cpp

00001 /*
00002     This file is part of KOrganizer.
00003     Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
00004     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 
00020     As a special exception, permission is given to link this program
00021     with any edition of TQt, and distribute the resulting executable,
00022     without including the source code for TQt in the source distribution.
00023 */
00024 
00025 #include "datenavigator.h"
00026 
00027 #include "koglobals.h"
00028 
00029 #include <kcalendarsystem.h>
00030 
00031 #include <kdebug.h>
00032 #include <kglobal.h>
00033 #include <klocale.h>
00034 
00035 using namespace KCal;
00036 
00037 DateNavigator::DateNavigator( TQObject *parent, const char *name )
00038   : TQObject( parent, name )
00039 {
00040   mSelectedDates.append( TQDate::currentDate() );
00041 }
00042 
00043 DateNavigator::~DateNavigator()
00044 {
00045 }
00046 
00047 DateList DateNavigator::selectedDates()
00048 {
00049   return mSelectedDates;
00050 }
00051 
00052 int DateNavigator::datesCount() const
00053 {
00054   return mSelectedDates.count();
00055 }
00056 
00057 void DateNavigator::selectDates( const DateList &dateList )
00058 {
00059   if ( dateList.count() > 0 ) {
00060     mSelectedDates = dateList;
00061 
00062     emitSelected();
00063   }
00064 }
00065 
00066 void DateNavigator::selectDate( const TQDate &date )
00067 {
00068   TQDate d = date;
00069 
00070   if ( !d.isValid() ) {
00071     kdDebug(5850) << "DateNavigator::selectDates(TQDate): an invalid date was passed as a parameter!" << endl;
00072     d = TQDate::currentDate();
00073   }
00074 
00075   mSelectedDates.clear();
00076   mSelectedDates.append( d );
00077 
00078   emitSelected();
00079 }
00080 
00081 void DateNavigator::selectDates( int count )
00082 {
00083   selectDates( mSelectedDates.first(), count );
00084 }
00085 
00086 void DateNavigator::selectDates( const TQDate &d, int count, const TQDate &preferredMonth )
00087 {
00088   if ( count > MAX_SELECTABLE_DAYS ) {
00089     count = MAX_SELECTABLE_DAYS;
00090   }
00091 
00092   DateList dates;
00093 
00094   int i;
00095   for( i = 0; i < count; ++i ) {
00096     dates.append( d.addDays( i ) );
00097   }
00098 
00099   mSelectedDates = dates;
00100 
00101   emitSelected( preferredMonth );
00102 }
00103 
00104 void DateNavigator::selectWeekByDay( int weekDay, const TQDate &d, const TQDate &preferredMonth )
00105 {
00106   int dateCount = mSelectedDates.count();
00107   bool weekStart = ( weekDay == KGlobal::locale()->weekStartDay() );
00108   if ( weekStart && dateCount == 7 ) {
00109     selectWeek( d, preferredMonth );
00110   } else {
00111     selectDates( d, dateCount, preferredMonth );
00112   }
00113 }
00114 
00115 void DateNavigator::selectWeek()
00116 {
00117   selectWeek( mSelectedDates.first() );
00118 }
00119 
00120 void DateNavigator::selectWeek( const TQDate &d, const TQDate &preferredMonth )
00121 {
00122   int dayOfWeek = KOGlobals::self()->calendarSystem()->dayOfWeek( d );
00123 
00124   int weekStart = KGlobal::locale()->weekStartDay();
00125 
00126   TQDate firstDate = d.addDays( weekStart - dayOfWeek );
00127 
00128   if ( weekStart != 1 && dayOfWeek < weekStart ) {
00129     firstDate = firstDate.addDays( -7 );
00130   }
00131 
00132   selectDates( firstDate, 7, preferredMonth );
00133 }
00134 
00135 void DateNavigator::selectWorkWeek()
00136 {
00137   selectWorkWeek( mSelectedDates.first() );
00138 }
00139 
00140 void DateNavigator::selectWorkWeek( const TQDate &d )
00141 {
00142   int weekStart = KGlobal::locale()->weekStartDay();
00143 
00144   int dayOfWeek = KOGlobals::self()->calendarSystem()->dayOfWeek( d );
00145 
00146   TQDate currentDate = d.addDays( weekStart - dayOfWeek );
00147 
00148   if ( weekStart != 1 && dayOfWeek < weekStart ) {
00149     currentDate = currentDate.addDays( -7 );
00150   }
00151 
00152   mSelectedDates.clear();
00153   int mask = KOGlobals::self()->getWorkWeekMask();
00154 
00155   for ( int i = 0; i < 7; ++i ) {
00156     if( (1<< ((i + weekStart + 6) % 7)) & (mask) ) {
00157     mSelectedDates.append( currentDate.addDays(i) );
00158     }
00159   }
00160 
00161   emitSelected();
00162 }
00163 
00164 void DateNavigator::selectToday()
00165 {
00166   TQDate d = TQDate::currentDate();
00167 
00168   int dateCount = mSelectedDates.count();
00169 
00170   if ( dateCount == 7 ) {
00171     selectWeek( d );
00172   } else if ( dateCount == 5 ) {
00173     selectWorkWeek( d );
00174   } else {
00175     selectDates( d, dateCount );
00176   }
00177 }
00178 
00179 void DateNavigator::selectPreviousYear()
00180 {
00181   TQDate firstSelected = mSelectedDates.first();
00182   int weekDay = firstSelected.dayOfWeek();
00183   firstSelected = KOGlobals::self()->calendarSystem()->addYears( firstSelected, -1 );
00184 
00185   selectWeekByDay( weekDay, firstSelected );
00186 }
00187 
00188 void DateNavigator::selectPreviousMonth( const TQDate &currentMonth,
00189                                          const TQDate &selectionLowerLimit,
00190                                          const TQDate &selectionUpperLimit )
00191 {
00192   shiftMonth( currentMonth,
00193               selectionLowerLimit,
00194               selectionUpperLimit,
00195               -1 );
00196 }
00197 
00198 void DateNavigator::selectPreviousWeek()
00199 {
00200   TQDate firstSelected = mSelectedDates.first();
00201   int weekDay = firstSelected.dayOfWeek();
00202   firstSelected = KOGlobals::self()->calendarSystem()->addDays( firstSelected, -7 );
00203 
00204   selectWeekByDay( weekDay, firstSelected );
00205 }
00206 
00207 void DateNavigator::selectNextWeek()
00208 {
00209   TQDate firstSelected = mSelectedDates.first();
00210   int weekDay = firstSelected.dayOfWeek();
00211 
00212   firstSelected = KOGlobals::self()->calendarSystem()->addDays( firstSelected, 7 );
00213 
00214   selectWeekByDay( weekDay, firstSelected );
00215 }
00216 
00217 void DateNavigator::shiftMonth( const TQDate &currentMonth,
00218                                 const TQDate &selectionLowerLimit,
00219                                 const TQDate &selectionUpperLimit,
00220                                 int offset )
00221 {
00222   const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00223 
00224   TQDate firstSelected = mSelectedDates.first();
00225   int weekDay = firstSelected.dayOfWeek();
00226   firstSelected = calSys->addMonths( firstSelected, offset );
00227 
00228   /* Don't trust firstSelected to calculate the nextMonth. firstSelected
00229      can belong to a month other than currentMonth because KDateNavigator
00230      displays 7*6 days. firstSelected should only be used for selection
00231      purposes */
00232   const TQDate nextMonth = currentMonth.isValid() ?
00233                           calSys->addMonths( currentMonth, offset ) : firstSelected;
00234 
00235   /* When firstSelected doesn't belong to currentMonth it can happen
00236      that the new selection won't be visible on our KDateNavigators
00237      so we must adjust it */
00238   if ( selectionLowerLimit.isValid() &&
00239        firstSelected < selectionLowerLimit ) {
00240     firstSelected = selectionLowerLimit;
00241   } else if ( selectionUpperLimit.isValid() &&
00242               firstSelected > selectionUpperLimit ) {
00243     firstSelected = selectionUpperLimit.addDays( -6 );
00244   }
00245 
00246   selectWeekByDay( weekDay, firstSelected, nextMonth );
00247 }
00248 
00249 void DateNavigator::selectNextMonth( const TQDate &currentMonth,
00250                                      const TQDate &selectionLowerLimit,
00251                                      const TQDate &selectionUpperLimit )
00252 {
00253   shiftMonth( currentMonth,
00254               selectionLowerLimit,
00255               selectionUpperLimit,
00256               1 );
00257 }
00258 
00259 void DateNavigator::selectNextYear()
00260 {
00261   TQDate firstSelected = mSelectedDates.first();
00262   int weekDay = firstSelected.dayOfWeek();
00263   firstSelected = KOGlobals::self()->calendarSystem()->addYears( firstSelected, 1 );
00264 
00265   selectWeekByDay( weekDay, firstSelected );
00266 }
00267 
00268 void DateNavigator::selectPrevious()
00269 {
00270   int offset = -7;
00271   if ( datesCount() == 1 ) {
00272     offset = -1;
00273   }
00274 
00275   selectDates( mSelectedDates.first().addDays( offset ), datesCount() );
00276 }
00277 
00278 void DateNavigator::selectNext()
00279 {
00280   int offset = 7;
00281   if ( datesCount() == 1 ) {
00282     offset = 1;
00283   }
00284 
00285   selectDates( mSelectedDates.first().addDays( offset ), datesCount() );
00286 }
00287 
00288 void DateNavigator::selectMonth( int month )
00289 {
00290   const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00291 
00292   TQDate firstSelected = mSelectedDates.first();
00293   int weekDay = firstSelected.dayOfWeek();
00294 
00295   int day = calSys->day( firstSelected );
00296   calSys->setYMD( firstSelected, calSys->year( firstSelected ), month, 1 );
00297   int days = calSys->daysInMonth( firstSelected );
00298   // As day we use either the selected date, or if the month has less days
00299   // than that, we use the max day of that month
00300   if ( day > days ) {
00301     day = days;
00302   }
00303   TQDate requestedMonth;
00304   calSys->setYMD( firstSelected, calSys->year( firstSelected ), month, day );
00305   calSys->setYMD( requestedMonth, calSys->year( firstSelected ), month, 1 );
00306 
00307   selectWeekByDay( weekDay, firstSelected, requestedMonth );
00308 }
00309 
00310 void DateNavigator::selectYear( int year )
00311 {
00312   TQDate firstSelected = mSelectedDates.first();
00313   int deltaYear = year - KOGlobals::self()->calendarSystem()->year( firstSelected );
00314   firstSelected = KOGlobals::self()->calendarSystem()->addYears( firstSelected, deltaYear );
00315 
00316   int weekDay = firstSelected.dayOfWeek();
00317   selectWeekByDay( weekDay, firstSelected );
00318 }
00319 
00320 void DateNavigator::emitSelected( const TQDate &preferredMonth )
00321 {
00322   emit datesSelected( mSelectedDates, preferredMonth );
00323 }
00324 
00325 #include "datenavigator.moc"