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 ¤tMonth, 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 ¤tMonth, 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 ¤tMonth, 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"