korganizer

datenavigator.cpp
1 /*
2  This file is part of KOrganizer.
3  Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
4  Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20  As a special exception, permission is given to link this program
21  with any edition of TQt, and distribute the resulting executable,
22  without including the source code for TQt in the source distribution.
23 */
24 
25 #include "datenavigator.h"
26 
27 #include "koglobals.h"
28 
29 #include <kcalendarsystem.h>
30 
31 #include <kdebug.h>
32 #include <tdeglobal.h>
33 #include <tdelocale.h>
34 
35 using namespace KCal;
36 
37 DateNavigator::DateNavigator( TQObject *parent, const char *name )
38  : TQObject( parent, name )
39 {
40  mSelectedDates.append( TQDate::currentDate() );
41 }
42 
43 DateNavigator::~DateNavigator()
44 {
45 }
46 
47 DateList DateNavigator::selectedDates()
48 {
49  return mSelectedDates;
50 }
51 
52 int DateNavigator::datesCount() const
53 {
54  return mSelectedDates.count();
55 }
56 
57 void DateNavigator::selectDates( const DateList &dateList )
58 {
59  if ( dateList.count() > 0 ) {
60  mSelectedDates = dateList;
61 
62  emitSelected();
63  }
64 }
65 
66 void DateNavigator::selectDate( const TQDate &date )
67 {
68  TQDate d = date;
69 
70  if ( !d.isValid() ) {
71  kdDebug(5850) << "DateNavigator::selectDates(TQDate): an invalid date was passed as a parameter!" << endl;
72  d = TQDate::currentDate();
73  }
74 
75  mSelectedDates.clear();
76  mSelectedDates.append( d );
77 
78  emitSelected();
79 }
80 
81 void DateNavigator::selectDates( int count )
82 {
83  selectDates( mSelectedDates.first(), count );
84 }
85 
86 void DateNavigator::selectDates( const TQDate &d, int count, const TQDate &preferredMonth )
87 {
88  if ( count > MAX_SELECTABLE_DAYS ) {
89  count = MAX_SELECTABLE_DAYS;
90  }
91 
92  DateList dates;
93 
94  int i;
95  for( i = 0; i < count; ++i ) {
96  dates.append( d.addDays( i ) );
97  }
98 
99  mSelectedDates = dates;
100 
101  emitSelected( preferredMonth );
102 }
103 
104 void DateNavigator::selectWeekByDay( int weekDay, const TQDate &d, const TQDate &preferredMonth )
105 {
106  int dateCount = mSelectedDates.count();
107  bool weekStart = ( weekDay == TDEGlobal::locale()->weekStartDay() );
108  if ( weekStart && dateCount == 7 ) {
109  selectWeek( d, preferredMonth );
110  } else {
111  selectDates( d, dateCount, preferredMonth );
112  }
113 }
114 
115 void DateNavigator::selectWeek()
116 {
117  selectWeek( mSelectedDates.first() );
118 }
119 
120 void DateNavigator::selectWeek( const TQDate &d, const TQDate &preferredMonth )
121 {
122  int dayOfWeek = KOGlobals::self()->calendarSystem()->dayOfWeek( d );
123 
124  int weekStart = TDEGlobal::locale()->weekStartDay();
125 
126  TQDate firstDate = d.addDays( weekStart - dayOfWeek );
127 
128  if ( weekStart != 1 && dayOfWeek < weekStart ) {
129  firstDate = firstDate.addDays( -7 );
130  }
131 
132  selectDates( firstDate, 7, preferredMonth );
133 }
134 
135 void DateNavigator::selectWorkWeek()
136 {
137  selectWorkWeek( mSelectedDates.first() );
138 }
139 
140 void DateNavigator::selectWorkWeek( const TQDate &d )
141 {
142  int weekStart = TDEGlobal::locale()->weekStartDay();
143 
144  int dayOfWeek = KOGlobals::self()->calendarSystem()->dayOfWeek( d );
145 
146  TQDate currentDate = d.addDays( weekStart - dayOfWeek );
147 
148  if ( weekStart != 1 && dayOfWeek < weekStart ) {
149  currentDate = currentDate.addDays( -7 );
150  }
151 
152  mSelectedDates.clear();
153  int mask = KOGlobals::self()->getWorkWeekMask();
154 
155  for ( int i = 0; i < 7; ++i ) {
156  if( (1<< ((i + weekStart + 6) % 7)) & (mask) ) {
157  mSelectedDates.append( currentDate.addDays(i) );
158  }
159  }
160 
161  emitSelected();
162 }
163 
164 void DateNavigator::selectToday()
165 {
166  TQDate d = TQDate::currentDate();
167 
168  int dateCount = mSelectedDates.count();
169 
170  if ( dateCount == 7 ) {
171  selectWeek( d );
172  } else if ( dateCount == 5 ) {
173  selectWorkWeek( d );
174  } else {
175  selectDates( d, dateCount );
176  }
177 }
178 
179 void DateNavigator::selectPreviousYear()
180 {
181  TQDate firstSelected = mSelectedDates.first();
182  int weekDay = firstSelected.dayOfWeek();
183  firstSelected = KOGlobals::self()->calendarSystem()->addYears( firstSelected, -1 );
184 
185  selectWeekByDay( weekDay, firstSelected );
186 }
187 
188 void DateNavigator::selectPreviousMonth( const TQDate &currentMonth,
189  const TQDate &selectionLowerLimit,
190  const TQDate &selectionUpperLimit )
191 {
192  shiftMonth( currentMonth,
193  selectionLowerLimit,
194  selectionUpperLimit,
195  -1 );
196 }
197 
198 void DateNavigator::selectPreviousWeek()
199 {
200  TQDate firstSelected = mSelectedDates.first();
201  int weekDay = firstSelected.dayOfWeek();
202  firstSelected = KOGlobals::self()->calendarSystem()->addDays( firstSelected, -7 );
203 
204  selectWeekByDay( weekDay, firstSelected );
205 }
206 
207 void DateNavigator::selectNextWeek()
208 {
209  TQDate firstSelected = mSelectedDates.first();
210  int weekDay = firstSelected.dayOfWeek();
211 
212  firstSelected = KOGlobals::self()->calendarSystem()->addDays( firstSelected, 7 );
213 
214  selectWeekByDay( weekDay, firstSelected );
215 }
216 
217 void DateNavigator::shiftMonth( const TQDate &currentMonth,
218  const TQDate &selectionLowerLimit,
219  const TQDate &selectionUpperLimit,
220  int offset )
221 {
222  const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
223 
224  TQDate firstSelected = mSelectedDates.first();
225  int weekDay = firstSelected.dayOfWeek();
226  firstSelected = calSys->addMonths( firstSelected, offset );
227 
228  /* Don't trust firstSelected to calculate the nextMonth. firstSelected
229  can belong to a month other than currentMonth because KDateNavigator
230  displays 7*6 days. firstSelected should only be used for selection
231  purposes */
232  const TQDate nextMonth = currentMonth.isValid() ?
233  calSys->addMonths( currentMonth, offset ) : firstSelected;
234 
235  /* When firstSelected doesn't belong to currentMonth it can happen
236  that the new selection won't be visible on our KDateNavigators
237  so we must adjust it */
238  if ( selectionLowerLimit.isValid() &&
239  firstSelected < selectionLowerLimit ) {
240  firstSelected = selectionLowerLimit;
241  } else if ( selectionUpperLimit.isValid() &&
242  firstSelected > selectionUpperLimit ) {
243  firstSelected = selectionUpperLimit.addDays( -6 );
244  }
245 
246  selectWeekByDay( weekDay, firstSelected, nextMonth );
247 }
248 
249 void DateNavigator::selectNextMonth( const TQDate &currentMonth,
250  const TQDate &selectionLowerLimit,
251  const TQDate &selectionUpperLimit )
252 {
253  shiftMonth( currentMonth,
254  selectionLowerLimit,
255  selectionUpperLimit,
256  1 );
257 }
258 
259 void DateNavigator::selectNextYear()
260 {
261  TQDate firstSelected = mSelectedDates.first();
262  int weekDay = firstSelected.dayOfWeek();
263  firstSelected = KOGlobals::self()->calendarSystem()->addYears( firstSelected, 1 );
264 
265  selectWeekByDay( weekDay, firstSelected );
266 }
267 
268 void DateNavigator::selectPrevious()
269 {
270  int offset = -7;
271  if ( datesCount() == 1 ) {
272  offset = -1;
273  }
274 
275  selectDates( mSelectedDates.first().addDays( offset ), datesCount() );
276 }
277 
278 void DateNavigator::selectNext()
279 {
280  int offset = 7;
281  if ( datesCount() == 1 ) {
282  offset = 1;
283  }
284 
285  selectDates( mSelectedDates.first().addDays( offset ), datesCount() );
286 }
287 
288 void DateNavigator::selectMonth( int month )
289 {
290  const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
291 
292  TQDate firstSelected = mSelectedDates.first();
293  int weekDay = firstSelected.dayOfWeek();
294 
295  int day = calSys->day( firstSelected );
296  calSys->setYMD( firstSelected, calSys->year( firstSelected ), month, 1 );
297  int days = calSys->daysInMonth( firstSelected );
298  // As day we use either the selected date, or if the month has less days
299  // than that, we use the max day of that month
300  if ( day > days ) {
301  day = days;
302  }
303  TQDate requestedMonth;
304  calSys->setYMD( firstSelected, calSys->year( firstSelected ), month, day );
305  calSys->setYMD( requestedMonth, calSys->year( firstSelected ), month, 1 );
306 
307  selectWeekByDay( weekDay, firstSelected, requestedMonth );
308 }
309 
310 void DateNavigator::selectYear( int year )
311 {
312  TQDate firstSelected = mSelectedDates.first();
313  int deltaYear = year - KOGlobals::self()->calendarSystem()->year( firstSelected );
314  firstSelected = KOGlobals::self()->calendarSystem()->addYears( firstSelected, deltaYear );
315 
316  int weekDay = firstSelected.dayOfWeek();
317  selectWeekByDay( weekDay, firstSelected );
318 }
319 
320 void DateNavigator::emitSelected( const TQDate &preferredMonth )
321 {
322  emit datesSelected( mSelectedDates, preferredMonth );
323 }
324 
325 #include "datenavigator.moc"