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
35using namespace KCal;
36
37DateNavigator::DateNavigator( TQObject *parent, const char *name )
38 : TQObject( parent, name )
39{
40 mSelectedDates.append( TQDate::currentDate() );
41}
42
43DateNavigator::~DateNavigator()
44{
45}
46
47DateList DateNavigator::selectedDates()
48{
49 return mSelectedDates;
50}
51
52int DateNavigator::datesCount() const
53{
54 return mSelectedDates.count();
55}
56
57void DateNavigator::selectDates( const DateList &dateList )
58{
59 if ( dateList.count() > 0 ) {
60 mSelectedDates = dateList;
61
62 emitSelected();
63 }
64}
65
66void 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
81void DateNavigator::selectDates( int count )
82{
83 selectDates( mSelectedDates.first(), count );
84}
85
86void 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
104void 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
115void DateNavigator::selectWeek()
116{
117 selectWeek( mSelectedDates.first() );
118}
119
120void 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
135void DateNavigator::selectWorkWeek()
136{
137 selectWorkWeek( mSelectedDates.first() );
138}
139
140void 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
164void 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
179void 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
188void 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
198void 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
207void 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
217void 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
249void 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
259void 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
268void 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
278void 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
288void 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
310void 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
320void DateNavigator::emitSelected( const TQDate &preferredMonth )
321{
322 emit datesSelected( mSelectedDates, preferredMonth );
323}
324
325#include "datenavigator.moc"